2017-12-13 16 views
0

私はTPLデータフローの完璧なシナリオである必要が生じたプロジェクトに取り組んでいます。比較的限られた経験(私がしていたことはもう少し前に行われました)を持っていたので、私はMicrosoftのドキュメントとオンラインで見つけられる記事を読んでいました。私は見つけることができない(記事にTPLのデータフロー、ブロック、および継続タスクの理解

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; 

誰か:

はそれをやってしまってから、私は一緒にチェーンにブロック(主に TransformBlockと、このような何かをやって ActionBlockで終わる一連の私のコードを構築しました)完全としてのブロックをマークするためにパイプラインで継続タスクがなければならないことが示唆された。これは、彼らがそのために提供されたコードである。

// 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にハングアップし、パイプラインを実行することはありません。

私はここで何が起こっているのかのニュアンスをよりよく理解したいので、私は追加の説明をお待ちしております。

+0

質問ごとに複数の質問をする必要はありません。さらに、いくつかのコンセプトの全体を説明することは、Too Broadです。あなたは*単一の、特定の*質問をしている必要があります。 – Servy

+0

@Servy私は最初の質問を削除しました。第2部にどうやって尋ねることをお勧めしますか?私は誰かがそれが重要であると言った理由を理解していないコードを提供しました(そしてその記事はそれを説明しませんでした)。この時点で、私はそれを理解するのを助けた何かを見つけたり読んだりしなかった。 – JasCav

+0

ブロックの完成度については何も見つかりませんでした。競技の仕組みのニュアンスをすべて説明してくれる人が必要ですか?最初の部分については、ブロックの仕組みがどのように機能しているのかについての情報がたくさんあります。もう1つは、あまりにも広いです。 – Servy

答えて

1

リニアパイプラインで行う必要があるのは、PropagateCompletionです。そのオプションはCompletion伝播ならびにその例外、最終Completion Taskに取り付けられFaults

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

継続は不要です。しかし、複数のブロックに分配するパイプラインがあれば、完了と障害伝播を自分で処理する必要がありますas shown here

コードはawait継続ので、あなたが完全block1その後、Complete()を決して呼び出していない前にそれを行うので、もし、たまたまその最初のContinueWith

にハングアップします。

関連する問題