Reputation: 15457
Why is the following example blocking? I was expecting "Run First" to run immediately and then 5 seconds later the "Run Last" would appear.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Call SomeAsyncCode() somehow
SomeAsyncCode().GetAwaiter().GetResult();
Console.WriteLine("Run First");
}
private static async Task SomeAsyncCode()
{
// Use await here!
await Task.Delay(5000);
Console.WriteLine("Run Last");
// Other async goodness...
}
}
}
Upvotes: 1
Views: 641
Reputation: 81493
You are awaiting (term used loosely) the task.
It would make more sense if you didn't use .GetAwaiter().GetResult();
(which are internal framework methods anyway) and just wrote
SomeAsyncCode().Wait();
Console.WriteLine("Run First");
It then becomes obvious whats happening, you are waiting for the task to complete.
The following is probably more like what you expect;
// start task
var task = SomeAsyncCode();
Console.WriteLine("Run First");
task.Wait();
In all honesty though, it should be rare to need to call, Wait
, Result
or GetAwaiter().GetResult()
on an async
method, doing so in a UI app, or something with a Synchronization Context will likely cause a deadlock
Ideally you let async
and await
propagate, in C# 7.1 and higher you have the ability to create an async
Entry Point which allows you use the Async and Await Pattern in a more succinct manner
static async Task Main(string[] args)
{
await SomeAsyncCode();
Console.WriteLine("Run First");
}
or
static async Task Main(string[] args)
{
var task = SomeAsyncCode();
Console.WriteLine("Run First");
await Task.WhenAll(task);
}
Upvotes: 5
Reputation: 4002
When you define async Task Method()
- you are telling that this method should be awaited even though it will return nothing.
When you define async void Method()
- you are telling that this is fire'n'forget method and you don't want to await it.
Also, when you void Main(string[] args)
is returning - your application is closing and GC will kill all your tasks.
So, your code should be more like this:
static void Main(string[] args)
{
// Call SomeAsyncCode() somehow
SomeAsyncCode();
Console.WriteLine("Run First");
Console.ReadKey(); // you need this to prevent app from closing
}
private static async void SomeAsyncCode()
{
// Use await here!
await Task.Delay(5000);
Console.WriteLine("Run Last");
// Other async goodness...
}
Upvotes: 1