缩进lambdas和嵌套操作 [英] Indenting lambdas and nested actions
问题描述
当使用lambdas,通常在TPL,我迷失在缩进...有没有一些最佳实践来格式化这个?例如,取这个代码:
When using lambdas, usually on TPL, I get lost on indentation... Are there some best practices to format this? For example, take this code:
Task t1 = factory.StartNew(() =>
{
DoSomething();
}
.ContinueWith((t2) =>
{
DoSomethingWhenComplete();
}, TaskContinuationOptions.OnlyOnRanToCompletion)
).ContinueWith((t3) =>
{
DoSomethingOnError();
}, TaskContinuationOptions.OnlyOnFaulted);
- 我的缩进是否正确?
- 在该示例中,我想要执行t1,然后如果它完成了OK,执行t2,并且在执行t3时出错。但看起来好像t3是从t2,而不是从t1 ...的延续...我需要修复在代码中得到正确的行为?
推荐答案
有一些最佳做法来格式化这个?
There are some best practice to format this?
我不知道任何。我的格式化看起来OK(除了下面的注释)。或者,您可以按照Visual Studio自动格式化(尝试从编辑器/高级菜单中设置文档格式)。
I'm not aware of any. Your formatting looks OK by me (besides the notes below). Alternatively, you may just follow Visual Studio automatic formatting (try Format Document from Editor/Advanced menu).
t1,如果完成确认执行t2,并且
错误执行t3。但是看起来t3是从t2继续,而不是从
t1 ...我需要修复该代码纠正行为?我认为我是
丢失的缩进或丢失一些括号...
In that example, I want execute t1 then if finish ok execute t2 and on error execute t3. But looks that t3 is continuation from t2, not from t1... What I need fix that code to correct behaviour? I think that I'm lost on that indentation or missing some parenthesis...
您的问题的代码片段甚至不会编译。您可能想要这样:
The code fragment from your question would not even compile. You probably wanted this:
Task t1 = factory.StartNew(() =>
{
DoSomething();
});
t1.ContinueWith((t2) =>
{
DoSomethingWhenComplete();
}, TaskContinuationOptions.OnlyOnRanToCompletion);
t1.ContinueWith((t2) =>
{
DoSomethingOnError();
}, TaskContinuationOptions.OnlyOnFaulted);
这可能有效,但是你缺少另一个状态: OnlyOnCanceled
。我宁愿在同一个地方处理
t1
的所有完成状态:
This may work, but you're missing another state: OnlyOnCanceled
. I'd rather handle all completion statuses of t1
in the same place:
Task t1 = factory.StartNew(() =>
{
DoSomething();
}).ContinueWith((t2) =>
{
if (t2.IsCanceled)
DoSomethingWhenCancelled();
else if (t2.IsFaulted)
DoSomethingOnError(t1.Exception);
else
DoSomethingWhenComplete();
});
这仍然可能会遗漏一件事:你的代码将在没有同步上下文的随机池线程。例如,如果你在UI线程上调用 ContinueWith
,你将无法访问 DoSomething *
方法。如果这是不您的期望,请明确指定任务计划程序继续:
This still might be missing one thing: your code will be continued on a random pool thread without synchronization context. E.g, if you called ContinueWith
on a UI thread, you won't be able to access the UI inside DoSomething*
methods. If that's not what you expected, explicitly specify the task scheduler for continuation:
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
。
If you need to target .NET 4.0 but use VS2012+ as your development environment, consider using async/await
and Microsoft.Bcl.Async
instead of ContinueWith
. It's much easier to code, more readable and will give you structured error handling with try/catch
.
无法使用async / await,请考虑使用任务。 模式由Stephen Toub完成任务链(详情请参阅这里)。
If you can't use async/await, consider using Task.Then pattern by Stephen Toub for task chaining (more details here).
这篇关于缩进lambdas和嵌套操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!