【问题标题】:How to properly write a custom Task returning method如何正确编写自定义任务返回方法
【发布时间】:2012-09-15 05:09:27
【问题描述】:

对于异步运行代码(例如使用 async/await),我需要一个适当的任务。当然,框架中有几个预定义的方法涵盖了最常用的操作,但有时我想编写自己的方法。我是 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;
    }

一般来说,我创建和使用像 Foo 示例这样的方法,但是有一个包含整个方法逻辑的“额外”lambda,它看起来不太漂亮恕我直言。另一种选择是使用任何方法,如 Bar 示例,但我认为这更糟糕,因为不清楚该方法是否应该异步运行(除了正确的方法名称,如 BarAsync)并且 Task.Factory.StartNew 可能必须在程序中重复多次。我不知道如何只告诉编译器‘这个方法返回一个任务,请在调用时将它作为一个整体包装到一个任务中’这是我想要做的。

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

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

【问题讨论】:

  • "without adding an additional named method of course" 为什么拒绝这个选项?创建public bool Barpublic Task&lt;bool&gt; BarAsync
  • 我想避免开销。如果使用同步或异步方法是有意义的,那就没问题了。如果没有,就会有一个公共 BarAsync 和一个私有 Bar(隐藏它),在这种情况下,我看不出有什么理由。

标签: c# task-parallel-library async-await


【解决方案1】:

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

我会说你的代码应该看起来像 Bar 那样,除非绝对必要,在任何情况下,都应该在不启动新的 Task 的情况下运行该代码。

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 1970-01-01
  • 2017-02-01
  • 2017-03-15
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多