當乙個task需要執行時,首先需要新增到taskscheduler類的乙個佇列中排隊,taskscheduler會從佇列中取task,放到執行緒中執行,預設情況下的taskscheduler會將task放到執行緒池中的執行緒上執行。
task.start和task.continuewith都包含了可以傳入taskscheduler引數的版本,利用這個引數可以控制task在哪個執行緒上執行。
以下我們建立了乙個自己的taskscheduler類,在taskscheduler類中建立一條單獨的執行緒用來執行task。
執行結果:class mytaskscheduler : taskscheduler
= new mytaskscheduler();
public static new taskscheduler default = current;
private readonly blockingcollectionm_queue = new blockingcollection();
mytaskscheduler()
private void run()
");task t;
while (m_queue.trytake(out t, timeout.infinite))
}protected override ienumerablegetscheduledtasks()
protected override void queuetask(task task)
//當執行該函式時,程式正在嘗試以同步的方式執行task**
protected override bool tryexecutetaskinline(task task, bool taskwaspreviouslyqueued)
}class program
"); for (int i = 0; i < 10; i++)
");});
t.start(mytaskscheduler.current);
}console.readkey();}}
以下是乙個使用了await的函式:
這函式執行的**和以下**類似:static async taskfun()
函式會先獲取synchronizationcontext.currenttask t = asyncfun();
var currentcontext = synchronizationcontext.current;
if (null == currentcontext)
, taskscheduler.current);
}else
, taskscheduler.fromcurrentsynchronizationcontext());
}
物件,這個物件預設情況下,在控制台程式中為
null
,在gui
程式中不為
null
。當synchronizationcontext.current==null
時會直接將後續**當作乙個
task
在taskscheduler.current
上執行,如果不等於
null
,則會將**在如下taskscheduler.fromcurrentsynchronizationcontext()上。
在gui
程式中synchronizationcontext.current
物件的post
方法和send
方法可以傳送一段**給主線程執行,對於函式
taskscheduler.fromcurrentsynchronizationcontext
返回值實際上其內部會呼叫
post
方法,將**傳送到主線程執行,這樣主線程呼叫的函式使用了
await
,函式await
後面的**依然會在主線程執行,可以防止其他執行緒呼叫主線程
ui控制項而崩潰。
擴充套件閱讀
在控制台程式中使用
synchronizationcontext物件
.net
非同步程式設計
C 非同步程式設計
同步方法和非同步方法的區別 同步方法呼叫在程式繼續執行之前需要等待同步方法執行完畢返回結果 非同步方法則在被呼叫之後立即返回以便程式在被呼叫方法完成其任務的同時執行其它操作 非同步程式設計概覽 net framework 允許您非同步呼叫任何方法。定義與您需要呼叫的方法具有相同簽名的委託 公共語言執...
C 非同步程式設計
一 基礎知識 1 非同步程式設計 2 非同步方法 乙個程式呼叫某個方法,在處理完成前就返回該方法。同步和非同步主要用於修飾方法。當乙個方法被呼叫時,呼叫者需要等待該方法執行完畢並返回才能繼續執行,我們稱這個方法是同步方法 當乙個方法被呼叫時立即返回,並獲取乙個執行緒執行該方法內部的業務,呼叫者不用等...
C 非同步程式設計
定義要求 方法簽名包含 async 修飾符。按照約定,非同步方法的名稱以 async 字尾結尾。返回型別為下列型別之一 1.如果你的方法有運算元為 tresult 型別的返回語句,則為 task。2.如果你的方法沒有返回語句或具有沒有運算元的返回語句,則為 task。3.void 如果要編寫非同步事...