c# - 缩进 lambda 和嵌套操作

标签 c# lambda coding-style task-parallel-library

当使用 lambda 时,通常在 TPL 上,我会迷失在缩进中……是否有一些最佳实践来格式化它?例如,拿这段代码:

Task t1 = factory.StartNew(() =>
{
    DoSomething();
}
.ContinueWith((t2) =>
{
    DoSomethingWhenComplete();
}, TaskContinuationOptions.OnlyOnRanToCompletion)
).ContinueWith((t3) =>
{
    DoSomethingOnError();
}, TaskContinuationOptions.OnlyOnFaulted);
  1. 我的“缩进”是否正确?
  2. 在那个例子中,我想执行 t1,然后如果它成功完成,则执行 t2,如果出错则执行 t3。但看起来 t3 是 t2 的延续,而不是 t1 的延续......我需要在该代码中修复什么才能获得正确的行为?我认为我迷失了那个缩进或遗漏了一些括号......

最佳答案

There are some best practice to format this?

我一个都不知道。我觉得你的格式没问题(除了下面的注释)。或者,您可以只遵循 Visual Studio 自动格式化(尝试从编辑器/高级菜单设置文档格式)。

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...

您问题中的代码片段甚至无法编译。你可能想要这个:

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/awaitMicrosoft.Bcl.Async 而不是 ContinueWith。它更容易编写代码,更具可读性,并且可以使用 try/catch 为您提供结构化的错误处理。

如果您不能使用 async/await,请考虑使用 Stephen Toub 的 Task.Then 模式进行任务链(更多详细信息 here )。

关于c# - 缩进 lambda 和嵌套操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21465699/

相关文章:

php - 在相等比较会给出与严格相等比较相同的结果的情况下,应该使用两者中的哪一个?

java - Lambda 表达式条件的代码覆盖率单元测试

c++ - lambda 的默认捕获是什么?

c# - Regex.replace 不会用开始字符替换多行文本行到 html block

c# - 如何执行容器ViewModel与包含的ViewModel之间的通信?

java - 如何删除 lambda 表达式的变量?

JavaDoc:在哪里向文档添加注释/备注?

c# - 如果我的函数在逻辑上只返回自然数,我应该使用 uint 吗?

c# - 是否可以找到 View 模型引用的属性

c# - 在单例中播种 Random() 的最佳方法