1

Method 1:

private static async Task FirstDelayAsync()
{
    await Task.Delay(1000);
}

Method 2:

private static Task SecondDelayAsync()
{
    return Task.Delay(1000);
}

Please help me to find the difference:

await FirstDelayAsync();
await SecondDelayAsync();

Thanks.

Ralph Willgoss
  • 11,750
  • 4
  • 64
  • 67
Leo Vo
  • 9,980
  • 9
  • 56
  • 78
  • 5
    One is called `First`, the other `Second`. One is `async`, the other not. This isn't http://puzzling.stackexchange.com. What do you actually want to know? Is your question [how to asynchronously call a synchronous method](http://stackoverflow.com/questions/18830397/awaiting-a-non-async-method)? – CodeCaster Mar 08 '16 at 11:07
  • 1
    @CodeCaster: This is a legitimate question. Even if there were no functional differences between the two (which isn't the case), the OP is justified in asking. It might, however, be a duplicate question. – Douglas Mar 08 '16 at 11:16
  • Marked as duplicate in the interest of DRY. Despite its title, the linked question and its accepted answer discuss mainly the case of `Task.Delay`, not `Task.Run`. – Douglas Mar 08 '16 at 11:34
  • @Douglas I'm not saying it's not legitimate, I'm saying it is unclear to me what kind of answers the OP is looking for. – CodeCaster Mar 08 '16 at 11:36

2 Answers2

4

The two are very similar. When it encounters an async method, the C# compiler will generate a state machine, such that the returned Task represents the completion of your method. Since the only thing that your method does is await another asynchronous operation, then this will be functionally almost equivalent to returning the Task from the inner asynchronous operation directly.

There is, however, a subtle difference concerning how exceptions from the synchronous part will be thrown. Any logic performed within async methods, including the synchronous part at the beginning of the method (before the first await statement), will be compiled as part of the asynchronous operation. This means that precondition exceptions will no longer be delivered synchronously, but asynchronously through the returned Task:

private static async Task FirstDelayAsync()
{
    if (StateNotValid)
        throw new NotSupportedException();

    await Task.Delay(1000);
}

private static Task SecondDelayAsync()
{
    if (StateNotValid)
        throw new NotSupportedException();

    return Task.Delay(1000);
}

Testing out the above code:

var t1 = FirstDelayAsync();
await t1;                       // exception thrown here

var t2 = SecondDelayAsync();    // exception thrown here
await t2;

This won't make a difference if you await your asynchronous operation on the same line that you call it. However, it would make a difference if you delay the awaiting; for example, if you launch several asynchronous operations concurrently and then await them together using Task.WhenAll:

var tasks = Enumerable
    .Range(0, 10)
    .Select(i => ProcessAsync(i))
    .ToArray();

await Task.WhenAll(tasks);

In the above snippet, synchronous exceptions thrown from the ProcessAsync calls would prevent the subsequent asynchronous operations from even being launched, since the exception immediately stops the enumeration. This is usually preferable for failed preconditions that should stop the entire process.

Update: Another important different is that using await without ConfigureAwait(false) will make your code more liable to deadlock. See this answer.

Community
  • 1
  • 1
Douglas
  • 53,759
  • 13
  • 140
  • 188
0

Functionally, there is no difference between the two methods. They work the same.

async and await allow you to create complex asynchronous methods by allowing you to write code that looks like synchronous code but is actually asynchronous.

For simple cases like the one you have, the second approach is preferred since the first approach creates a state machine to handle the asynchronous logic. Such state machine is definitely needed in case of complex asynchronous methods, but is not needed for this simple case.

Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62