在下面的代码中,由于接口的原因,类LazyBar必须从其方法返回一个任务(出于参数的原因,不能更改).如果LazyBar的实现是不寻常的,因为它恰好运行得很快和同步-从该方法返回无操作任务的最佳方式是什么?

我在下面提到了Task.Delay(0),但是我想知道如果函数被称为lot,这是否会对性能产生任何副作用(为了论证起见,比如每秒数百次):

  • 这个句法上的糖是不是会变成什么大事呢?
  • 它开始阻塞我的应用程序的线程池了吗?
  • 编译器是否足够灵活,能够以不同的方式处理Delay(0)
  • return Task.Run(() => { });有什么不同吗?

有没有更好的方法?

using System.Threading.Tasks;

namespace MyAsyncTest
{
    internal interface IFooFace
    {
        Task WillBeLongRunningAsyncInTheMajorityOfImplementations();
    }

    /// <summary>
    /// An implementation, that unlike most cases, will not have a long-running
    /// operation in 'WillBeLongRunningAsyncInTheMajorityOfImplementations'
    /// </summary>
    internal class LazyBar : IFooFace
    {
        #region IFooFace Members

        public Task WillBeLongRunningAsyncInTheMajorityOfImplementations()
        {
            // First, do something really quick
            var x = 1;

            // Can't return 'null' here! Does 'Task.Delay(0)' have any performance considerations?
            // Is it a real no-op, or if I call this a lot, will it adversely affect the
            // underlying thread-pool? Better way?
            return Task.Delay(0);

            // Any different?
            // return Task.Run(() => { });

            // If my task returned something, I would do:
            // return Task.FromResult<int>(12345);
        }

        #endregion
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            Test();
        }

        private static async void Test()
        {
            IFooFace foo = FactoryCreate();
            await foo.WillBeLongRunningAsyncInTheMajorityOfImplementations();
            return;
        }

        private static IFooFace FactoryCreate()
        {
            return new LazyBar();
        }
    }
}

推荐答案

今天,我建议使用Task.CompletedTask来实现这一点.


之前.净4.6:

与使用无操作表达式创建Task相比,使用Task.FromResult(0)Task.FromResult<object>(null)会产生更少的开销.当使用预先确定的结果创建Task时,不涉及调度开销.

.net相关问答推荐

dotnet 8 web api在部署到docker后无法工作

如何运行大量阻塞/同步 I/O 操作

在c#中计算中位数

如何从标头中检索基本身份验证凭据?

JavaScript 中的IsNullOrWhitespace?

如何以编程方式判断类型是 struct 还是类?

mstest.exe 在哪里?

我可以从 .NET/C# 获取其他进程的命令行参数吗?

.Net 中的 Decimal.One、Decimal.Zero、Decimal.MinusOne 的用途是什么

String.Split 仅在 C# 中的第一个分隔符上?

我应该在 LINQ 查询中使用两个where子句还是&&?

WCF服务客户端:内容类型text/html;响应消息的charset=utf-8 与绑定的内容类型不匹配

.NET 事件 - 什么是对象发送者和 EventArgs e?

何时使用抽象类?

如何保护我的 .NET 程序集免受反编译?

ASP.NET Core (.NET Core) 和 ASP.NET Core (.NET Framework) 的区别

资源(.resx)文件有什么好处?

如何判断对象是否已在 C# 中释放

/langversion 的错误选项6无效;必须是 ISO-1、ISO-2、3、4、5 或默认值

如何为我的 C# 应用程序创建产品密钥?