2014-11-07 2 views
1

Учитывая этот код:завершая TPL потока данных цепь

s_Batch = new BatchBlock<PerformanceRecord>(500); 
s_Action = new ActionBlock<PerformanceRecord[]>(a => SendToDatabase(a)); 
s_Batch.LinkTo(s_Action); 

, когда я закончу мне нужно позвонить Complete() на каждом блоке? Или завершится s_Batch, чтобы запустить в блоках, связанных с ним?

+0

Возможный дубликат [TPL Dataflow, завершение гарантии, только когда все исходные блоки данных источника завершены] (http://stackoverflow.com/questions/13510094/tpl-dataflow-guarantee-completion-only-when-all-source-data -blocks-completed) –

+0

Соответствует ли вышеуказанный ответ вашим потребностям? –

ответ

5

Как ваш код стоит сейчас, вам нужно позвонить Complete по всем блокам индивидуально:

s_Batch.Complete(); 
await s_Batch.Completion; 

s_Action.Complete(); 
await s_Action.Completion; 

Вы можете однако использовать DataflowLinkOptions в то время как связывающая блоки для запроса распространения завершающего:

s_Batch.LinkTo(s_Action, new DataflowLinkOptions {PropagateCompletion = true}); 
s_Batch.Complete(); 
await s_Batch.Completion; 

Это будет распространять как завершение, так и уведомление о сбое на связанный целевой блок (то есть s_Action).

1

Мне нравится ответ на 3-й этаж, поскольку он является самым кратким.

Это что-то еще, что я сделал/видел с блоками TPL, которые также работают.

s_Batch.Completion.ContinueWith(t => 
    { 
     if(t.IsFaulted) 
      ((IDataFlowBlock)s_Action).Fault(t.Exception); 
     else 
      s_Action.Complete(); 
    }); 
s_Batch.Complete(); 
s_Action.Completion.Wait(); 

Даунсайд является то, что вам нужно будет повторить этот шаблон для каждого связанного блока, так что вы в конечном итоге повторяя себе совсем немного.

Смежные вопросы