task多线程 - c# task用法




如果我的界面必须返回任务什么是无操作实现的最佳方式? (4)

在下面的代码中,由于接口的原因,类LazyBar必须从它的方法中返回一个任务(并且为了参数不能改变)。 如果LazyBar的实现非常不寻常,因为它发生在快速同步运行 - 从方法返回无操作任务的最佳方式是什么?

我已经使用了下面的Task.Delay(0) ,但是我想知道如果这个函数被调用了很多 (为了参数,每秒数百次),这是否会有任何性能副作用:

  • 这个句法糖是否会让某些东西变大?
  • 它是否开始堵塞我的应用程序的线程池?
  • 编译器切割器是否足以以不同的方式处理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.Delay(0)与答案中的一样是一个好方法,因为它是已完成Task的缓存副本。

从4.6开始,现在有更明确的Task.CompletedTask ,但Task.Delay(0)不仅返回单个缓存实例,而且返回 Task.CompletedTask 相同的单个缓存实例。

两者的缓存性质都保证不变,但是作为依赖于实现的优化只作为优化实现(也就是说,如果实现更改为仍然有效的,它们仍然可以正常工作)使用Task.Delay(0)比接受的答案好。


使用Task.FromResult(0)Task.FromResult<object>(null)将比使用no-op表达式创建Task开销少。 在创建预定义结果的Task时,不会涉及任何调度开销。

今天,我会推荐使用Task.CompletedTask来完成这个任务。


最近遇到这个,并不断收到有关该方法无效的警告/错误。

我们正在安抚编译器,并清除它:

    public async Task MyVoidAsyncMethod()
    {
        await Task.CompletedTask;
    }

这汇集了迄今为止所有建议中最好的。 除非您真的在方法中做某件事,否则不需要返回声明。


要增加Reed Copsey有关使用Task.FromResult 的回答 ,如果缓存已完成的任务,则可以提高性能,因为所有已完成任务的实例都是相同的:

public static class TaskExtensions
{
    public static readonly Task CompletedTask = Task.FromResult(false);
}

使用TaskExtensions.CompletedTask您可以在整个应用程序域中使用相同的实例。

最新版本的.Net Framework(v4.6)只是增加了Task.CompletedTask静态属性

Task completedTask = Task.CompletedTask;




threadpool