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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With