Asynchronous method that does nothing

11,377

Solution 1

Just use Task.CompletedTask to return a completed task:

public Task BeginAsync()
{
     return Task.CompletedTask;
}

If you have a Task<TResult> use Task.FromResult<TResult> to return a completed task with a result:

public Task<bool> BeginAsync()
{
     return Task.FromResult(true);
}

Your current implementation is very inefficient, as it builds the state machine, and also uses a ThreadPool thread to run the empty task.

Solution 2

It's very easy to fall into the trap of thinking that async must be part of the signature of any asynchronous method. It looks it must be; it (misleadingly!) reads as if it's whole purpose is to mark a method as asynchronous.

But it's not, Task or Task<T> are required, but not async. This is shown in @ReedCopsey's answer and in the following correct example (slightly adapted from this useful SO answer):

public Task<int> MethodTaskAsync(int arg0, int arg1)
{
    Task<int> task = new Task<int>(() => Method(arg0, arg1));
    task.Start(); // Hot task (started task) should always be returned.
    return task;
}

That's why interface method signatures don't need, and can't have, the async keyword: an 'asynchronous' method per se, without regard to how it might be implemented, is just a method that returns a started (and, possibly, already finished) Task or Task<T>.

If async doesn't mark a method as asynchronous, what does it do? It's a way to write asynchronous methods more simply: once you have applied it to a method, you can use the await keyword to tell the compiler to correctly handle subsidiary asynchronous calls for you very simply (without it, you could try to handle subsidiary Tasks manually, using lots more code like that in the code block above, but to do so would be very complex and error prone).

So if you just want to return a do-nothing, already-completed task from an 'asynchronous' (i.e. Task-returning) method, you can and should do so synchronously(!), as in @ReedCopsey 's answers, using Task.CompletedTask or Task.FromResult(...).

Share:
11,377

Related videos on Youtube

Fabio Marcolini
Author by

Fabio Marcolini

CONSUME

Updated on June 15, 2022

Comments

  • Fabio Marcolini
    Fabio Marcolini almost 2 years

    I have an interface IAnimation which exposes a method BeginAsync(). That method should start the animation and return when it is completed.

    What I would like to do is implement a null animation class NoAnimation that just returns when it executes BeginAsync().

    Is this the right implementation?

    public async Task BeginAsync()
    {
        await Task.Run(() => { });
    }
    

    I suspect that there is a more elegant approach than this. I also considered creating an empty method. But that gives me a warning which I don't like either.

  • Gianpiero
    Gianpiero about 6 years
    First method should be: await Task.CompletedTask;. Second method should be return await Task.FromResult(true); In addition tey require the async key. Please, fix your code
  • Reed Copsey
    Reed Copsey about 6 years
    @GianpieroCaretti No, that is absolutely bad advice. Using await when it is not needed adds zero benefit and extra overhead. What I have is correct.
  • C.List
    C.List over 5 years
    Should be noted that this property only available in .net 4.6+
  • cool breeze
    cool breeze over 4 years
    is there a one liner for this?
  • Reed Copsey
    Reed Copsey over 4 years
    @coolbreeze Task.CompletedTask and Task.FromResult are both already one liners...?
  • MikeBeaton
    MikeBeaton over 3 years
    @coolbreeze In C# 6.0+ (released in July 2015, so some time after you originally asked) you can now make the whole method a one liner, with public Task BeginAsync() => Task.CompletedTask;