缩进lambdas和嵌套操作 [英] Indenting lambdas and nested actions

查看:184
本文介绍了缩进lambdas和嵌套操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用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);




  1. 我的缩进是否正确?

  2. 在该示例中,我想要执行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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆