In the docs for TPL我找到了这一行:
从同一前项调用多个延续
但这没有进一步解释。我天真地假设您可以以类似模式的方式将 ContinueWiths 链接起来,直到您点击正确的TaskContinuationOptions
。
TaskThatReturnsString()
.ContinueWith((s) => Console.Out.WriteLine(s.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((f) => Console.Out.WriteLine(f.Exception.Message), TaskContinuationOptions.OnlyOnFaulted)
.ContinueWith((f) => Console.Out.WriteLine("Cancelled"), TaskContinuationOptions.OnlyOnCanceled)
.Wait();
但这不能像我希望的那样工作,至少有两个原因。
那么当他们说同一前提的多个延续时,它们在文档中意味着什么? 对此是否有适当的模式,还是我们只需要将调用包装在try catch块中即可?
编辑
所以我想这就是我希望做的,请注意,这是一个简化的示例。
public void ProccessAllTheThings()
{
var theThings = util.GetAllTheThings();
var tasks = new List<Task>();
foreach (var thing in theThings)
{
var task = util.Process(thing)
.ContinueWith((t) => Console.Out.WriteLine($"Finished processing {thing.ThingId} with result {t.Result}"), TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((t) => Console.Out.WriteLine($"Error on processing {thing.ThingId} with error {t.Exception.Message}"), TaskContinuationOptions.OnlyOnFaulted);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
因为这是不可能的,所以我想我必须将每个任务调用都包装在循环内的try catch中,这样我才不会停止该过程,而不必在那里等待。我不确定哪种方法正确。
有时候解决方案只是盯着你看,这行得通吗?
public void ProccessAllTheThings()
{
var theThings = util.GetAllTheThings();
var tasks = new List<Task>();
foreach (var thing in theThings)
{
var task = util.Process(thing)
.ContinueWith((t) =>
{
if (t.Status == TaskStatus.RanToCompletion)
{
Console.Out.WriteLine($"Finished processing {thing.ThingId} with result {t.Result}");
}
else
{
Console.Out.WriteLine($"Error on processing {thing.ThingId} - {t.Exception.Message}");
}
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
答案 0 :(得分:1)
您要做的是创建一个包含多个任务的顺序链。
您需要做的是将所有继续任务附加到第一个任务上:
var firstTask = TaskThatReturnsString();
var t1 = firstTask.ContinueWith (…);
var t2 = firstTask.ContinueWith (…);
var t3 = firstTask.ContinueWith (…);
然后,您需要等待所有继续任务:
Task.WaitAll (t1, t2, t3);