インターフェイスが Task を返す必要がある場合、操作なしの実装を行う最適な方法は何ですか? 質問する

インターフェイスが Task を返す必要がある場合、操作なしの実装を行う最適な方法は何ですか? 質問する

以下のコードでは、インターフェースのため、クラスはLazyBarメソッドからタスクを返す必要があります (議論のために変更できません)。LazyBars の実装が高速かつ同期的に実行されるという点で珍しい場合、メソッドから No-Operation タスクを返す最適な方法は何ですか?

私は以下のようにしましたが、関数が頻繁に呼び出された場合(議論のために、1 秒間に数百回とします)、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();
        }
    }
}

ベストアンサー1

今日は、タスク.完了したタスクこれを達成するために。


.net 4.6 以前:

Task.FromResult(0)または を使用すると、no-op 式でTask.FromResult<object>(null)を作成する場合よりもオーバーヘッドが少なくなります。結果が事前に決定された を作成する場合、スケジュールのオーバーヘッドは発生しません。TaskTask

おすすめ記事