在同步代码中实现需要返回Task类型的接口

4

当实现返回 Task<T> 的接口方法时,使用同步代码可以使用 Task.FromResult<T>(result)。当结果只是 Task 时,除了使用类似于 Task.FromResult<object>(null); 这样的方法之外,是否有更好的选项?


你不能只使用 await.Wait() 吗? - Shaun Wilde
@ShaunWilde 我不想要异步方法的开销。(看看这样做生成的IL代码吧。) - Paul
1
使用 Task.FromResult 创建已完成的任务并将其向上转换为非泛型的 Task 是最优雅的方法之一。不幸的是,个人认为最好坚持这种方法,并在某个静态字段中缓存一个已完成的 Task 实例,并继续重复使用它。 - Kirill Shlenskiy
Task.FromResult(0) 稍微短一些,但本质上是相同的。 - Alexei Levenkov
现在我们有Task.CompletedTask - rory.ap
2个回答

1
一般来说,答案是否定的。
一个“任务”是一个行动的“包装”,可以是lambda或委托。所以如果你想让你的方法返回一个“任务”对象,那么你需要实例化一个“任务”实例或从其他地方检索它。
要实例化一个“任务”实例,你有两种方法 - 使用构造函数或一些工厂方法。如前所述,“任务”包装了一个操作,因此在调用构造函数时需要提供一个操作。
static Task GetTask() 
{
    return new Task(() => { });
}

或者,如果您希望您的任务具有返回值,您可以按照以下方式操作。

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

另一种方法是使用工厂方法来创建这样的“Task”。Task.FactoryTask<T>.FromResult都是工厂方法,但两者都没有比您指定的更好的选项。因此,为了创建一个新实例,您确实需要调用可能具有某些必需参数的构造函数;或者您可以使用提供的某些工厂方法。如果您发现它们都不方便,我相信自定义的工厂/助手是您的解决方案。顺便说一下,基于C#类型推断,如果您的返回类型是像整数这样的具体类型,则可以通过省略已经足够简单的类型来编写以下代码:
static Task GetTask() 
{
    return Task.FromResult(123);
}

由于您的示例返回了null,所以类型无法推断,因此您需要在代码中指定它(object)。

1

将接受的答案更改为正确答案已更改。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接