Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different implementations of a method that returns a Task

This is something I've come across while refactoring some legacy code.

Consider a method on an interface that returns a Task:

public interface IFoo
{
    Task Bar();
}

The Bar method implementation can be implemented in two ways:

Returning a Task:

public class Foo1 : IFoo
{
    public Task Bar()
    {
        return Task.Run(() =>
            {
                /* some work */
            });
    }
}

Or using async ... await:

public class Foo2 : IFoo
{
    public async Task Bar()
    {
        await Task.Run(() =>
            {
                /* some work */
            });
    }
}

Are these implementations functionally equivalent, or are there (potentially subtle) differences?

like image 220
Richard Ev Avatar asked Nov 28 '25 14:11

Richard Ev


1 Answers

There is quite a difference since using the async-await syntax causes the compiler to generate code which actually continues past the await statement once the task finishes. Moreover, awaiting a task which has faulted results in the exception bubbling to the awaiter, meaning that it is no longer considered unobserved.. I think that there's more, and I really recommend you have a look at Jon Skeet's C# 5 Async course on pluralsight, he actually goes through compiler generated code and explains it.

like image 67
Eyal Perry Avatar answered Dec 01 '25 03:12

Eyal Perry