对于多个ContinueWith方法,是否有合适的模式



在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();

但这并没有像我希望的那样奏效,至少有两个原因。

  • continuations被正确地链接,因此第二个ContinueWith从第一个得到结果,即作为新的Task实现,基本上是ContinueWith任务本身。我意识到String可以继续返回,但这不是一个丢失了其他信息的新任务吗
  • 由于没有满足第一个选项,因此任务被取消。这意味着第二盘永远不会满足,例外情况也会丢失

那么,当他们在文档中说来自同一先行词的多个连续词时,他们的意思是什么?有合适的模式吗?还是我们只需要将调用封装在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());
}

您所做的是创建多个任务的顺序链。

你需要做的是将你所有的继续任务附加到第一个任务上:

var firstTask = TaskThatReturnsString();
var t1 = firstTask.ContinueWith (…);
var t2 = firstTask.ContinueWith (…);
var t3 = firstTask.ContinueWith (…);

然后你需要等待所有的继续任务:

Task.WaitAll (t1, t2, t3);

相关内容

  • 没有找到相关文章

最新更新