如何正确编写自定义任务返回方法

mar*_*rce 5 c# task-parallel-library async-await

为了异步运行代码(例如使用async/await),我需要一个合适的Task.当然,框架中有几种预定义的方法可以覆盖最频繁的操作,但有时我想编写自己的方法.我是C#的新手,所以很可能我做错了,但我至少对我目前的做法并不满意.请参阅以下示例了解我正在做的事情:

public async Task<bool> doHeavyWork()
    {
        var b1 = await this.Foo();
        //var b2 = await Task<bool>.Factory.StartNew(Bar); //using Task.Run
        var b2 =  await Task.Run(()=>Bar());
        return b1 & b2;
    }

public Task<bool> Foo()
    {
        return Task.Factory.StartNew(() =>
                                  {
                                      //do a lot of work without awaiting
                                      //any other Task
                                      return false;
                                  });
    }

public bool Bar()
    {
        //do a lot of work without awaiting any other task
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

一般来说,我创建和使用像Foo示例这样的方法,但是有一个'额外'的lambda包含整个方法逻辑,看起来不是很漂亮.另一个选择是使用任何方法,如Bar示例,但是我认为这更糟糕,因为不清楚这个方法应该运行async(除了正确的方法名称,如BarAsync)和Task.Factory.StartNew可能必须在程序中重复几次.我不知道如何告诉编译器'这个方法返回一个Task,请在调用时将它作为一个整体包装成'我想做的事.

最后我的问题是:编写这种方法的最佳方法是什么?我可以摆脱'额外'lambda(当然不添加额外的命名方法)吗?

编辑 正如Servy所说,总有充分的理由拥有该方法的同步版本.只有在absolutley必要时才应提供异步版本(Stephen Cleary的链接).

Ser*_*rvy 3

Bar如果有人想调用而不在新线程/任务中启动它,世界会结束吗?如果后台线程中已有另一个方法,因此不需要启动新任务来运行长时间运行的代码怎么办?如果该方法最终被重构为从桌面应用程序上下文以及 ASP 或控制台上下文调用的类库,该怎么办?在其他上下文中,该方法可能只需要直接运行,而不是作为Task.

我想说你的代码应该像Bar那里那样,除非绝对有必要在任何情况下都应该运行该代码而不启动新的Task.

另请注意,使用较新版本的 .NET,您应该从 .NET 切换到 .NET Task.Factory.StartNewTask.Run因此代码量应该会减少(一点点)。

  • 另请参阅:[我应该为同步方法公开异步包装器吗?](http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx) (3认同)