【问题标题】:Implementing an interface that requires a Task return type in synchronous code在同步代码中实现需要 Task 返回类型的接口
【发布时间】:2014-12-08 17:29:41
【问题描述】:

当使用同步代码实现返回Task<T> 的接口方法时,您可以使用Task.FromResult<T>(result)。当结果只是 Task 时,有没有比使用 Task.FromResult<object>(null); 之类的更好的选择?

【问题讨论】:

  • 你不能只使用await.Wait()吗?
  • @ShaunWilde 我不想要异步方法的开销。 (看看这样做会生成的 IL。)
  • 使用Task.FromResult 创建一个已完成的任务并将其向上转换到非通用的Task 是很不幸的。就我个人而言,我会坚持这一点,并将已完成的 Task 的单个实例缓存在某个静态字段中并继续重用它。
  • Task.FromResult(0) 有点短,但基本相同。
  • 现在我们有Task.CompletedTask

标签: c#


【解决方案1】:

一般来说答案是否定的。

Task 是动作的“包装”,可以是 lambda 或委托。因此,如果您希望您的方法返回一个 Task 对象,那么您需要实例化一个 Task 实例或从其他地方检索它。

要实例化 Task 实例,您有两种方法 - 使用构造函数或一些工厂方法。如前所述,Tasks 包装了一个动作,因此您需要在调用构造函数时提供一个动作

static Task GetTask() 
{
    return new Task(() => { });
}

或者如果你想让你的Task 有一个返回值,你可以这样做

static Task GetTask() 
{
    return new Task<object>(() => null);
}

另一种方法是使用工厂方法来创建这样的TaskTask.FactoryTask&lt;T&gt;.FromResult 都是工厂方法,但都没有比您指定的更好的选择。

同样,要创建一个新实例,您确实需要调用可能有一些必需参数的构造函数;或者您使用一些提供的工厂方法。如果您发现它们都不方便,我相信定制的工厂/助手是您的解决方案。

顺便说一下,基于 C# 类型推断,如果返回类型是具体类型,例如整数,则可以通过省略已经足够简单的类型来执行以下代码:

static Task GetTask() 
{
    return Task.FromResult(123);
}

您的示例是返回null,因此无法推断类型,因此您需要在代码中指定它(对象)。

【讨论】:

    【解决方案2】:

    是的:现在有 Task.CompletedTask 从 .NET 4.6 开始。

    【讨论】:

    • 随着正确答案的改变而改变接受的答案
    猜你喜欢
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 2012-10-06
    • 2011-05-16
    • 2015-01-01
    • 1970-01-01
    相关资源
    最近更新 更多