0
using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        var p = new Program();
        p.Loop();
    }

    public async void Loop()
    {
        for (int i = 0; i < 5; ++i)
        {
            try
            {
                Console.WriteLine(i);
                var result = await SomeTask();
                Console.WriteLine(result);
            }
            catch (Exception)
            {
                Console.WriteLine("Error" + i);
            }
        }
    }

    public async Task<string> SomeTask()
    {
        await Task.Delay(1);
        throw new Exception();
        return "Result";
    }
}

Output

0
Error0
1

I would expect the output to be more like this:

0
Error0
1
Error2
2
Error2
3
Error4
4

Why does it stop after 0?

i3arnon
  • 113,022
  • 33
  • 324
  • 344
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467

1 Answers1

2

You are not waiting for the async operation to complete and so the application ends before it the operation has a chance to complete.

You shouldn't be using async void outside of event handlers. async void doesn't return an awaitable and so the calling method simply moves on (and exits the app). You should return a Task and await it (or in the case of Main use Task.Wait):

public static void Main()
{
    var p = new Program();
    p.LoopAsync().Wait();
}

public async Task LoopAsync()
{
    for (int i = 0; i < 5; ++i)
    {
        try
        {
            Console.WriteLine(i);
            var result = await SomeTask();
            Console.WriteLine(result);
        }
        catch (Exception)
        {
            Console.WriteLine("Error" + i);
        }
    }
}

Output:

0
Error0
1
Error1
2
Error2
3
Error3
4
Error4
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • So with `await` in the `Main` method, the program will exit, because although `Main` is paused, `Main` still returns to its caller (which I assume is the Common Language Runtime.) Result: the `LoopAsync` cannot complete because the CLR has stopped hosting it (or something like that.) Details here: http://stackoverflow.com/questions/13140523/await-vs-task-wait-deadlock – Shaun Luttin Mar 27 '15 at 01:44
  • 1
    @ShaunLuttin You can only use `await` in an `async` method, which `Main` can't be. That's why you need to use `Wait` instead. When you don't wait, you run `LoopAsync` synchronously until it reaches the first `await`, then it returns to the caller, which is `Main` which ends and exits the app. – i3arnon Mar 27 '15 at 01:46