有格式化一些这方面的最佳做法?
我不知道任何。我的格式设置看起来不错(除了下面的注释)。或者,您可以按照Visual Studio自动格式化(尝试从编辑器/高级菜单中格式化文档)。
在那个例子中,我想要执行t1,然后如果完成ok请执行t2并且在 错误执行t3。但看起来T3是从t2延续,而不是从 t1 ...我需要修复该代码以纠正行为?我认为我是 在该缩进上丢失或缺少一些括号...
您问题的代码段甚至不会编译。你可能想这一点:
Task t1 = factory.StartNew(() =>
{
DoSomething();
});
t1.ContinueWith((t2) =>
{
DoSomethingWhenComplete();
}, TaskContinuationOptions.OnlyOnRanToCompletion);
t1.ContinueWith((t2) =>
{
DoSomethingOnError();
}, TaskContinuationOptions.OnlyOnFaulted);
这可以工作,但你错过了另一种状态:OnlyOnCanceled
。我宁愿处理的t1
所有完成的状态在同一个地方:
Task t1 = factory.StartNew(() =>
{
DoSomething();
}).ContinueWith((t2) =>
{
if (t2.IsCanceled)
DoSomethingWhenCancelled();
else if (t2.IsFaulted)
DoSomethingOnError(t1.Exception);
else
DoSomethingWhenComplete();
});
这仍然可能丢失一两件事:你的代码将在一个随机池线程继续进行,没有同步的情况下。例如,如果您在UI线程上调用ContinueWith
,则无法访问DoSomething*
方法中的UI。如果这是不你所期望的,明确指定任务调度的延续:
Task t1 = factory.StartNew(() =>
{
DoSomething();
}).
ContinueWith((t2) =>
{
if (t1.IsCanceled)
DoSomethingWhenCancelled();
else if (t1.IsFaulted)
DoSomethingOnError(t1.Exception);
else
DoSomethingWhenComplete();
}, TaskScheduler.FromCurrentSynchronizationContext());
如果你需要的目标.NET 4.0,但使用VS2012 +作为开发环境,可以考虑使用async/await
和Microsoft.Bcl.Async
而不是ContinueWith
。代码更容易编写,更具可读性,并可为您提供try/catch
的结构化错误处理。
如果您不能使用异步/等待,请考虑使用Stephen Toub的Task.Then模式进行任务链接(更多详细信息here)。
不错!但考虑将'StartNew'下一行移至与'ContinueWith'相同的缩进级别。 – Lightman
@Lightman我现在要坚持我的丑陋缩进;-)。我尝试用我的推理更新我的答案。基本上,我不想将参数缩进超过前一行缩进的一个以上的级别,因为我通常不会进行简单的方法调用。我希望所有的延续都要缩进以澄清它们是第一行开始的声明的一部分。 – binki