Lets refine your code. First it doesn't work, because you told the code to await a(), and so nothing after that line can run before (or during) it. Lets fix it:
static async Task Main()
{
var task = a();
b();
await task;
}
However that is not enough, it still doesn't work. It still runs a() before b() because your a method is not asynchronous. In fact it is synchronous. Just because you use async/await it doesn't make the code automatically asynchronous. You'll need more than that. One way is to add await Task.Yield() which is truely asynchronous call, even though it does nothing (except for allowing the switch to happen). Like this:
async static Task a()
{
Console.WriteLine("Waiting for a");
for (int i = 0; i < 100000000; i++)
if (i % 1000000 == 0)
{
Console.Write(".");
await Task.Yield();
}
Console.WriteLine("\na");
}
Now you will see b() running in the middle of a(). You can play around with the await Task.Yield(); call, and put it in different places to see different result.
This is still a bit primitive example. It would be better to make b() asynchronous as well. And use delays. Like this:
public class program
{
static async Task Main()
{
var task1 = a();
var task2 = b();
await task1;
await task2;
}
async static Task a()
{
Console.WriteLine("Waiting for a");
for (var i = 0; i < 100; i++)
{
Console.Write(".");
await Task.Delay(20);
}
Console.WriteLine("\na");
}
static async Task b()
{
await Task.Delay(200);
Console.WriteLine("b");
}
}
Note that I've slightly modified your a() so that it is more time dependent, less cpu-speed dependent.
Of course you have a thread-safety issue now, which in this case is ok since Console and Task methods are thread-safe. But generally you have to be aware that when two or more Tasks run concurrently then they may run on different threads, and thus you have to make the code thread-safe.