在 TPL 的文档中,我发现了这一行:
从同一个先行词调用多个延续
但这没有进一步解释。我天真地假设您可以以类似模式匹配的方式链接ContinueWithsTaskContinuationOptions
,直到您找到正确的方法。
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();
但这并不像我希望的那样工作,至少有两个原因。
- 延续被正确链接,因此第二个 ContinueWith 从第一个获得结果,即作为新任务实现,基本上是 ContinueWith 任务本身。我意识到可以继续返回字符串,但这不是丢失其他信息的新任务吗?
- 由于不满足第一个选项,因此任务被取消。这意味着永远不会满足第二组并且会丢失异常。
那么当他们说来自同一个先行词的多个延续时,他们在文档中的意思是什么?是否有适当的模式,或者我们只需要将调用包装在 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());
}