2

I'm just test some async and await with simple functions. Now the output of Console.WriteLine(foo()) is System.Threading.Tasks.Task1[System.Int32]. I'd like to know how to make it return 1

static async Task<int> Delay1() { await Task.Delay(1000); return 1; }
static async Task<int> Delay2() { await Task.Delay(2000); return 2; }
static async Task<int> Delay3() { await Task.Delay(3000); return 3; }
static async Task<int> foo()
{ 
    Task<int> winningTask = await Task.WhenAny(Delay1(), Delay2(), Delay3());
    //int r = winningTask.Result;
    //return r;
    await winningTask;
    return winningTask.Result;

}

static void Main(string[] args)
{           
    Console.WriteLine("Done");
    Console.WriteLine(foo()); // 1
    Console.WriteLine(Delay1().Result);
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344
baozi
  • 679
  • 10
  • 30
  • 1
    What's wrong with `Console.WriteLine(foo().Result);`? (will deadlock in WinForm, but you have console app so it's ok). – Alexei Levenkov Sep 23 '14 at 16:18
  • 1
    Also check out [Await, SynchronizationContext, and Console Apps](http://blogs.msdn.com/b/pfxteam/archive/2012/02/02/10263555.aspx) blog posts for a way of running `async` methods from console. – Alexei Levenkov Sep 23 '14 at 16:24
  • And likely duplicate by Stephen Cleary - http://stackoverflow.com/questions/17630506/async-at-console-app-in-c – Alexei Levenkov Sep 23 '14 at 16:26
  • 3
    what's wrong with `return await winningTask;`? – Peter Ritchie Sep 23 '14 at 16:30
  • 1
    You just need to get the result of the task returned by `foo()`, see @I3arnon's answer. – Peter Ritchie Sep 23 '14 at 16:33
  • @PeterRitchie it did work with your way of returning a task and call `Console.WriteLine(foo().Result))` with output `1`;But why can't directly return an `int` using `return winningTask.Result` like i did? – baozi Sep 23 '14 at 16:36
  • @XunBao you *do* directly return int, but the return value of foo() is `Task` if you don't unwrap it with `await`, you have to deal with the `Task` directly (i.e. `.Result`) – Peter Ritchie Sep 23 '14 at 16:43

1 Answers1

4

It seems you have some misunderstandings about the usage of async-await. await not only asynchronously waits for a task to complete, it also extracts the task's result and throws its first exception if it has one.

static async Task<int> foo()
{ 
    Task<int> winningTask = await Task.WhenAny(Delay1(), Delay2(), Delay3());
    return await winningTask;
}

As long as your method can be an async one you should use await:

static async Task Test()
{           
    Console.WriteLine("Done");
    Console.WriteLine(await foo());
    Console.WriteLine(await Delay1());
}

static void Main()
{           
    Test().Wait();
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344