If my interface must return Task what is the best way to have a no-operation implementation?

.net, async-await, c#, task-parallel-library, threadpool

Solution

Today, I would recommend using Task.CompletedTask to accomplish this.

Pre .net 4.6:

Using `Task.FromResult(0)` or `Task.FromResult<object>(null)` will incur less overhead than creating a `Task` with a no-op expression. When creating a `Task` with a result pre-determined, there is no scheduling overhead involved.

Problem

In the code below, due to the interface, the class `LazyBar` must return a task from its method (and for argument's sake can't be changed). If `LazyBar`s implementation is unusual in that it happens to run quickly and synchronously - what is the best way to return a No-Operation task from the method? I have gone with `Task.Delay(0)` below, however I would like to know if this has any performance side-effects if the function is called a lot (for argument's sake, say hundreds of times a second): - Does this syntactic sugar un-wind to something big? - Does it start clogging up my application's thread pool? - Is the compiler cleaver enough to deal with `Delay(0)` differently? - Would `return Task.Run(() => { });` be any different? Is there a better way? ``` 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(); } } } ```

Original source

Related problems