假设我们有两个工作人员函数:
void Step1(); // Maybe long.
void Step2(); // Might be short clean up of step 1.我经常看到:
Task.Run(() => Step1()).ContinueWith(t => Step2());它创建2任务,运行在系列中。在以下情况下:
Task.Run(() => { Step1(); Step2(); });它创建了一个单任务,运行系列中的两个函数,这似乎是一个更简单的选择。
是否有常识的指导方针可以用来确定什么时候比简单的方法更需要延续?
上面的例子没有异常处理-异常处理对这些准则有什么影响?
发布于 2015-08-19 09:10:37
是否有常识的指导方针可以用来确定什么时候比简单的方法更需要延续?
ContinueWith为您提供了仅在特定条件下通过TaskContinutationOptions调用Step2的能力,如OnlyOnCanceled OnlyOnFaulted、OnlyOnRanToCompletion等。这样,您就可以组成一个适合每种情况的工作流。
您也可以使用单个Task.Run和try-catch来完成这一任务,但这可能更需要您维护。
就我个人而言,我试图避免使用ContinueWith,因为我发现async-await不那么冗长,而且更像同步。我宁愿await在try-catch里面。
发布于 2015-08-19 09:10:32
我认为有两个主要原因:
ContinueWith方法允许您轻松地组合许多不同的任务,并使用助手方法构建“延续树”。将其更改为命令式调用限制了这一点--这仍然是可能的,但任务比命令式代码更可组合。
在ContinueWith情况下,Step2总是运行,即使Step1抛出。当然,这可以用一个try子句来模仿,但它要复杂一些。最重要的是,它不能组合,而且不能很好地扩展--如果您发现您必须运行多个步骤,每个步骤都有各自的错误处理,那么您将很难处理try-catches。当然,Task不是这方面的唯一解决方案,也不一定是最好的--一个错误单体也可以让您轻松地组合相互依赖的操作。
发布于 2015-08-19 09:10:51
通常,使用最少数量的延续就可以了。它们混淆了代码和成本性能。
这样做的原因之一是异常行为。即使第一个任务失败,也会继续运行。在这里,据我所知,没有错误行为。在这段代码中,这似乎不是一个问题。您需要以某种方式处理来自t的异常。
人们常常在想:“我有一条管道!”把管道分解成几个步骤。这是很自然的想法。但是管道步骤不一定需要以延续的形式表现出来。它们只需对方法调用进行排序。
https://stackoverflow.com/questions/32091109
复制相似问题