我有一个TPL数据流管道,消息的条件链接流可能在图片中所示的任何一个操作块处结束。
我还将PropogateCompletion设置为True,这与整个管道中使用的链接选项相同。
一旦我通过将上下文传递到第一个TransformBlock来启动流程,它将启动流程上下文,其中包含开始和结束时间以及一些有关处理记录的度量。
管道方法。
public void Process(CancellationToken token = default)
{
var linkOptions = new DataflowLinkOptions {PropagateCompletion = true};
var exBlockOptions = new ExecutionDataflowBlockOptions
{CancellationToken = token, MaxDegreeOfParallelism = Environment.ProcessorCount};
_context.Start();
var setMessagesToStartStatus = new TransformBlock<IContext, IContext>(async context =>
{
await _mRepository.SetMessagesToStartStatus(token);
return context;
}, exBlockOptions);
var autoMapMessageReferences =
new TransformBlock<IContext, IContext>(async context =>
{
await _mRepository.SetAutoMapMessageReferences(token);
return context;
},
exBlockOptions);
var messagesToProcess = new TransformManyBlock<IContext, AwsomeMessage>(
async context =>
{
var r = await _mRepository.GetPendingMessagesToProcess(token);
return r.ToList();
}, exBlockOptions);
var errActionBlock =
new ActionBlock<AwsomeMessage>(async inMessage =>
{
await _mRepository.SetToErrorState(inMessage.MessageId, inMessage.ErrorMessage, token);
_errorWorks.Add(inMessage);
}, exBlockOptions);
var printActionBlock = new ActionBlock<AwsomeMessage>(inMessage =>
{
Console.WriteLine(
$"ID :{inMessage.MessageId}, Error?: {inMessage.IsInError}, ErrorString :: {inMessage.ErrorMessage}");
_processedWorks.Add(inMessage);
}, exBlockOptions);
var updateSourceSystem = EnrichSourceSystemTransBlock(token, exBlockOptions);
var detoxReasonUpdate = EnrichDetoxReasonTransBlock(exBlockOptions);
var awsomeActionMapping = EnrichAwsomeActionMappingTransBlock(token, exBlockOptions);
var lateReasonMapToWorkAction = EnrichLateReasonTransBlock(exBlockOptions);
var updateWithNarrationReason = EnrichReasonToOtherTransBlock(token, exBlockOptions);
var crossAmendedByAndOtherReason = EnrichCrossSystemTransBlock(exBlockOptions);
var PureEQDBookReplacement = EnrichPurexBookTransBlock(token, exBlockOptions);
var bookHierarchyEnrichMessage = EnrichBookHierarchyTransBlock(token, exBlockOptions);
//pipeline
setMessagesToStartStatus.LinkTo(autoMapMessageReferences, linkOptions);
autoMapMessageReferences.LinkTo(messagesToProcess, linkOptions);
messagesToProcess.LinkTo(updateSourceSystem, linkOptions);
updateSourceSystem.LinkTo(detoxReasonUpdate, linkOptions);
detoxReasonUpdate.LinkTo(awsomeActionMapping, linkOptions);
awsomeActionMapping.LinkTo(errActionBlock, linkOptions, x => x.IsInError);
awsomeActionMapping.LinkTo(lateReasonMapToWorkAction, linkOptions, x => !x.IsInError);
lateReasonMapToWorkAction.LinkTo(updateWithNarrationReason, linkOptions);
updateWithNarrationReason.LinkTo(errActionBlock, linkOptions, x => x.IsInError);
updateWithNarrationReason.LinkTo(crossAmendedByAndOtherReason, linkOptions, x => !x.IsInError);
crossAmendedByAndOtherReason.LinkTo(PureEQDBookReplacement, linkOptions);
PureEQDBookReplacement.LinkTo(errActionBlock, linkOptions, x => x.IsInError);
PureEQDBookReplacement.LinkTo(bookHierarchyEnrichMessage, linkOptions, x => !x.IsInError);
bookHierarchyEnrichMessage.LinkTo(errActionBlock, linkOptions, x => x.IsInError);
bookHierarchyEnrichMessage.LinkTo(printActionBlock, linkOptions, x => !x.IsInError);
//Create Context
setMessagesToStartStatus.Post(_context);
//Kick off complete. -- Mark the head to say its complete.
try
{
setMessagesToStartStatus.Complete();
printActionBlock.Completion.Wait(token);
errActionBlock.Completion.Wait(token);
_context.Complete();
}
catch (AggregateException exception)
{
Debug.WriteLine(exception.Message);
foreach (var exc in exception.InnerExceptions)
{
Debug.WriteLine($"Err Msg = {exc.Message}, Stack Work = {exc.StackTrace} ");
}
throw exception.InnerExceptions.Single();
}
}
我尝试了Task.WhenAll,但它到底是怎么回事。它只是块。 由于传播完成是真的,我尝试了setMessagesToStartStatus.Complete.Wait()
当我完成此操作时,只要不做这件事就说任务已经完成并继续前进。
来自db的GetMessages是一个TransformManyBlock,当我仅传递一项进入错误块的测试数据时,由于甚至没有启动打印块,它现在进入挂起状态。所以完整不会影响。另一个问题是它没有等待。
已修复以下代码。
var completeFalseLinkOptions = new DataflowLinkOptions(){PropagateCompletion = false};
//Linking changes.
.LinkTo(errActionBlock, completeFalseLinkOptions, x => x.IsInError);
awsomeActionMapping.LinkTo(lateReasonMapToWorkAction, linkOptions, x => !x.IsInError);
lateReasonMapToWorkAction.LinkTo(updateWithNarrationReason, linkOptions);
updateWithNarrationReason.LinkTo(errActionBlock, completeFalseLinkOptions, x => x.IsInError);
updateWithNarrationReason.LinkTo(crossAmendedByAndOtherReason, linkOptions, x => !x.IsInError);
crossAmendedByAndOtherReason.LinkTo(PureEQDBookReplacement, linkOptions);
PureEQDBookReplacement.LinkTo(errActionBlock, completeFalseLinkOptions, x => x.IsInError);
PureEQDBookReplacement.LinkTo(bookHierarchyEnrichMessage, linkOptions, x => !x.IsInError);
bookHierarchyEnrichMessage.LinkTo(errActionBlock, completeFalseLinkOptions, x => x.IsInError);
bookHierarchyEnrichMessage.LinkTo(printActionBlock, linkOptions, x => !x.IsInError);
//and Complete Wait here.
setMessagesToStartStatus.Complete();
printActionBlock.Completion.Wait(token);
//manually complete the error block.
errActionBlock.Complete();
errActionBlock.Completion.Wait(token);
_context.Complete();