簡體   English   中英

了解TPL數據流,塊和延續任務

[英]Understanding TPL Dataflow, Blocks, and Continuation Tasks

我正在一個需要滿足TPL Dataflow理想情況的項目中工作。 由於對它的經驗相對有限(並且我之前做過的事情),我一直在閱讀Microsoft的文檔以及可以在網上找到的文章來進行梳理。

完成此操作后,我構建了將一系列塊鏈接在一起的代碼(主要是TransformBlock並以一個ActionBlock結尾,如下所示:

var block1 = new TransformBlock<T, U>(async input => {});
var block2 = new TransformBlock<U, V>(async input => {});
var block3 = new ActionBlock<V>(async input => {});

block1.LinkTo(block2);
block2.LinkTo(block3);

foreach(var item in items)
{
   await block1.SendAsync(item);
}
block1.Complete();
await block3.Completion;

文章中的某人(我找不到)建議管道中應該有繼續任務,以將塊標記為已完成。 這是他們為此提供的代碼。

// Create the continuation tasks in the pipeline that marks each block as complete.
await block1.Completion.ContinueWith(t =>
{
    if (t.IsFaulted) { ((IDataflowBlock)block2).Fault(t.Exception); }
    else { block2.Complete(); }
});
await block2.Completion.ContinueWith(t =>
{
    if (t.IsFaulted) { ((IDataflowBlock)block3).Fault(t.Exception); }
    else { block3.Complete(); }
});

我承認我不完全了解此代碼的功能以及是否需要它。 當我嘗試在我剛剛編寫的代碼中運行此代碼時,該代碼將掛在第一個ContinueWith ,並且永遠不會使其運行管道。

我希望能得到更多的解釋,因為我想更好地了解這里發生的細微差別。

對於線性管道,您所需要做的就是PropagateCompletion 該選項會傳播“ Completion ”以及“ Faults ,然后將其異常附加到最終“ Completion Task

var linkOptions = new DataflowLinkOptions() { PropagateCompletion = true };
block1.LinkTo(block2, linkOptions);
block2.LinkTo(block3, linkOptions);

繼續是不必要的。 但是,如果您有分配給多個塊的管道,則需要自己處理完成和錯誤傳播,如下所示

該代碼掛在第一個ContinueWith

發生這種情況是因為您await繼續,所以如果您在調用Complete()之前這樣做,那么block1將永遠不會完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM