【问题标题】:What to return from non-async method with Task as the return type?从以 Task 作为返回类型的非异步方法返回什么?
【发布时间】:2014-05-09 09:21:11
【问题描述】:

假设我有一个不是异步但返回 Task 的方法(因为定义来自一个也用于异步实现的接口)

public Task DoWorkAsync(Guid id)
{
     // do the work

     return ...;
}

返回的最佳对象是什么?我目前的选择:

return Task.Yield();
return Task.FromResult<object>(null);

// any of the other but cached in a static field and reused.

【问题讨论】:

  • 旁注 - 如果可能,则引入没有异步操作的单独接口(ISP 原则)
  • @SergeyBerezovskiy - 在这种情况下,最大的问题是调用者必须根据提供的实现(例如,通过 IoC)在两个接口之间切换。我可以在两者之间创建一个包装器,但对于它来说,原始问题仍然很重要。

标签: c# async-await


【解决方案1】:

在 Microsoft.net 4.6 中,Task 类有一个用于此目的的静态属性。

Task.CompletedTask

https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.completedtask(v=vs.110).aspx

【讨论】:

    【解决方案2】:

    你不能返回Task.Yield(),它不是Task而是YieldAwaitable用于await,它实际上引入了异步(我发布了一些more details here)。

    我为此使用Task.FromResult(Type.Missing)。也许,最有效但未记录的选项是Task.Delay(0)it returns a static completed task

    【讨论】:

    • +1。我喜欢Task.FromResult&lt;object&gt;(null),但.NET 团队更喜欢Task.FromResult(0)。但是,它们都没有被缓存。
    • 我喜欢无证选项。我想知道假设0x4000 总是意味着“不处置”并因此自己创建和缓存new Task(false, (TaskCreationOptions)0x4000, System.Threading.CancellationToken.None) 有多安全......
    • @Knaģis,这可能是个坏主意,他们可以随时更改 :) 另外,此构造函数覆盖是私有的,您需要使用反射。
    • @Noseratio - 是的,我想了很多......所以我目前的方法将是 private static Task _CompletedTask = Task.Delay(0); public static Task CompletedTask { get { return _CompletedTask; } } 这也使我能够替换实现,以防将来 Task.Delay(0) 不再是一个禁止 -操作。
    • @Noseratio,我想知道为什么您强调了您的首选方法返回唯一任务对象的事实 - 我目前无法弄清楚在我的代码中任务的引用相等性很重要的场景.. .
    猜你喜欢
    • 1970-01-01
    • 2011-10-24
    • 2012-08-09
    • 2022-06-21
    • 2013-05-31
    • 1970-01-01
    • 2015-09-04
    • 2016-10-05
    • 2018-06-10
    相关资源
    最近更新 更多