[英]Does Task objects internally contain a collection of ContinueWith tasks?
我正在讀一本書,上面寫着:
任務對象內部包含 ContinueWith 任務的集合。 因此,您實際上可以使用單個任務 object 多次調用 ContinueWith。 當任務完成時,所有的 ContinueWith 任務都會排隊到線程池中。
所以我嘗試檢查任務https 的源代碼://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,146
我沒有找到任何看起來像 ContinueWith 任務集合的私有字段。
所以我的問題是,Task 對象內部是否包含 ContinueWith 任務的集合?
如果是這樣,假設我們有以下代碼:
Task<Int32> t = Task.Run(() => Sum(10000));
Task a = t.ContinueWith(task => Console.WriteLine("The sum is: " + task.Result),
TaskContinuationOptions.OnlyOnRanToCompletion);
Task b = t.ContinueWith(task => Console.WriteLine("Sum threw: " + task.Exception.InnerException),
TaskContinuationOptions.OnlyOnFaulted);
if (a == b) {
... // false
{
既然調用ContinueWith
只是在集合中添加一個項,那么a
和b
應該指向同一個 Task object,但是a == b
返回 false?
我想你可以說答案是肯定的和否定的。 任務 class 使用互鎖以跟上繼續。
您可以在第 4727 行看到添加名為 AddTaskContinuationComplex(object tc, bool addBeforeOthers) 的延續的方法。在此方法中,延續被添加到列表中,然后傳遞給 Interlocked。
// Construct a new TaskContinuation list
List<object> newList = new List<object>();
// Add in the old single value
newList.Add(oldValue);
// Now CAS in the new list
Interlocked.CompareExchange(ref m_continuationObject, newList, oldValue);
現在,如果您查看 FinishContinuations(第 3595 行)方法,您可以看到
// Atomically store the fact that this task is completing. From this point on, the adding of continuations will
// result in the continuations being run/launched directly rather than being added to the continuation list.
object continuationObject = Interlocked.Exchange(ref m_continuationObject, s_taskCompletionSentinel);
TplEtwProvider.Log.RunningContinuation(Id, continuationObject);
在這里,當前任務被標記為已完成,下一個任務正在從 Interlocked 中獲取。
現在,如果您將 go 連接到聯鎖 class並檢查它,您會發現雖然它本身不一定是一個集合,但它以線程安全的方式跟上並維護延續。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.