[英]Task Parallel Library - how to return immediately but have a parallel step
我具有以下需要以非阻塞并行处理方式进行的工作流程。 我希望方法DoStuff()
立即返回,所以我正在使用任务并行库
DoStuff():
Do some setup
Parse an Excel file
then for each row
Fill Template with parsed values
Convert filled template to Pdf
Convert pdf to Tiff
when all row processing has completed Create Summary Text File
when summary text file has completed, Finalize
由于我想立即返回,因此我对“当所有行处理都已完成时”步骤有些脚。 以下是我应该做什么?
public Task<ProcessingResult> DoStuff() {
return new Task<SetupResult>(SetUp)
.ContinueWith(ParseExcel, TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith(excelProcessing => {
var templateProcessing = excelProcessing.Result.RowParsing
.Select(template =>
new Task<TemplateFillingResult>(()=>FillTemplate)
.ContinueWith(ConvertToPdf, TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith(ConvertToTiff, TaskContinuationOptions.OnlyOnRanToCompletion)
).ToArray()
//-------------------------------------------------------------
// This is the part that seems wierd
//-------------------------------------------------------------
Task.Factory.ContinueWhenAll(templateTasks, t=> { }).Wait();
return new TemplatesProcessingResult(templateProcessing);
}, TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith(CreateSummaryFile, TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith(FinalizeProcessing, TaskContinuationOptions.OnlyOnRanToCompletion);
我认为您会感到困惑,因为您尝试将所有这些组件连接为原始事件的延续。 如果没有令人信服的理由使所有这些调用都继续,则可以使用单个后台线程(任务)简单地完成所有操作。
var task = Task.Factory.StartNew(() =>
{
// setup
// var stuff = ParseFile()
// Executes elements in parallel and blocks this thread until all have completed, else bubbles the exception up
var transformations = excelProcessing.Result.RowParsing.AsParallel().Select(x =>
{
FillTemplate(x);
}).ToArray();
// create summary text file
// Finalize
return processingResult;
});
基本上,您可以在单个线程中完成所有这些操作,而不必担心。 将所有这些步骤标记为继续操作对于您需要做的事情来说是很复杂的。
然后,您的调用代码可以简单地阻塞那个家伙的Result
属性,以获取异步调用的结果:
try
{
var result = task.Result;
}
catch(AggregateException e)
{
e.Flatten().Handle(ex =>
{
// Do Stuff, return true to indicate handled
});
}
但是,您需要了解的一件事是例外。 如果这将是一劳永逸的任务,那么如果您有异常,它将一路冒起,并有可能杀死您的进程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.