2014-02-18 25 views
2

我正在處理task.GetAwaiter()面臨的一個問題任務OnCompleted觸發OnCompleted(新動作)任務並行 - 上畢竟ContinueWith

我有多個ContinueWith一個主要任務,但是當我返回主要任務並在OnCompleted上添加一個委託,它會在處理完主任務後觸發,而不是在所有ContinueWith之後觸發。我的問題是,有沒有辦法知道何時完成所有繼續?

這是我目前的代碼。

runningTask.Start(); 
    runningTask.GetAwaiter().OnCompleted(() => 
     { 
      KeyValuePair<int, Func<bool>> validator = validationList.FirstOrDefault(x => x.Key == runningTask.Id); 
      bool shouldContinue = validator.Value(); 
      if (shouldContinue) 
      { 
        validationList.Remove(validator.Key); 
        PerformExecutionByQueue(); 
      } 
     }); 

runningTask是這樣

Task runningTask = new Task(delegate method); 
Task secondTask = runningTask.ContinueWith(delegate method); 

等創建。 。 。

+0

請您正在使用的語言標記這一點。 –

+0

完成,感謝@RamanShah – DevEstacion

+0

你到底想幹什麼?如果要在任務完成時執行某些操作,只需在_proper_任務上使用ContinueWith。 TaskAwaiter主要由編譯器使用,如果OnComplete始終在特定任務完成執行時觸發,而不是在任務狀態發生更改(例如,RanToCompletion,Cancelled或Faulted)時觸發。 –

回答

1

將所有調用的結果存儲在某個類的集合中,然後使用Task.WhenAll在完成所有調用時執行一些代碼。

+0

改變了這個答案,更合乎邏輯,並修復了實際問題,沒有任何額外的字段 – DevEstacion

1

當你調用ContinueWith,試圖傳遞TaskContinuationOptions.AttachedToParent。這將告訴任務將繼續視爲父任務的一部分,並且在繼續完成之前不要完成父任務。這是假設,當然,父任務還沒有已經完成;如果有,則繼續將在您撥打ContinueWith()時在線執行。

1

ContinueWith創建一個secondTask只有在runningTask完成後才能運行。 secondTask並不妨礙runningTask精加工而成,所以OnCompleted事件後會runningTask結束immediatelly火。

如果你想防止runningTask精加工而成,而secondTask仍然運行在ContinueWith使用TaskContinuationOptions.AttachToParent,如:

Task secondTask = runningTask.ContinueWith(delegate method, 
        TaskContinuationOptions.AttachToParent); 

AttachToParent防止其父任務未能完成,直到所有的子任務已經完成。另外一個好處是,附加任務將顯示爲子任務的Visual Studio中的任務視圖

+0

我已經試過這個,但它仍然在runningTask後觸發。 – DevEstacion

+0

你在調用'ContinueWith()'之前是否啓動了'runningTask'?如果是這樣,那麼任務可以在繼續註冊之前完成,在這種情況下,可以在'secondTask'完成之前調用awaiter回調。 –

0

家長只需添加上類級別的事件,並要求其在最後繼續與固定它之下。