Reputation: 1263
I am learning TPL (async/await) from a tutorial and I tried to test it out myself using a console application. Please don't be offended by my ignorance. I am sure I am doing wrong somewhere- I wrote the following code:
static void Main(string[] args_)
{
Task<int> task = ProcessNumber(25);
Console.WriteLine(string.Format("{0}: Waiting started...", DateTime.Now));
task.Wait();
Console.WriteLine(string.Format("{0}: Waiting ended...", DateTime.Now));
Console.WriteLine(task.Result);
Console.WriteLine("Press any key to terminate!");
Console.ReadLine();
}
static async Task<int> ProcessNumber(int i_)
{
Thread.Sleep(1000);
var integer = await IncrementNumber(i_ * 23);
return integer;
}
static async Task<int> IncrementNumber(int j_)
{
Thread.Sleep(6000);
return (j_ + 23) / 23;
}
It's plain C# console code. My question is why do I get following output:
3/5/2015 5:22:37 PM: Waiting started...
3/5/2015 5:22:37 PM: Waiting ended...
26
Shouldn't there be considerable time gap between"Waiting started" and "Waiting Ended"?
UPDATE
After the answers, I figured out that Task.Delay(..) and Thread.Sleep(..) aren't same because they work very differently. Here is a nice link that explains with an example.
Seems it would be a mistake to consider TPL as yet another framework for multithreading. All the answers helped me , so I voted for all. However, I select Jon's answer as it is the most illustrative and the first one to appear. Thanks all!
Upvotes: 0
Views: 896
Reputation: 1812
you need to refactor your code. like this
static async Task<int> IncrementNumber(int j_)
{
await Task.Delay(...);
return (j_ + 23) / 23;
}
if you found CPU bound task instead of Thread.Sleep then you need to do something like this.
//it will create a new thread then sleep.
await Task.Run( () => ( CPUBoundTask());
var integer = await IncrementNumber(i_ * 23);
return integer;
Upvotes: 1
Reputation: 73502
It is because none of your methods are asynchronous. They pretend to be asynchronous by returning Task
but they all execute synchronously.
In fact you should be getting the compiler warning for IncrementNumber
number saying This async method lacks 'await' operators and will run synchronously... etc. It basically says that your method will be executed synchronously. This answer explains it in detail.
So when ProcessNumber
returns the whole nested methods calls are already finished synchronously.
Change the method to use await Task.Delay
instead of Thread.Sleep
to make it asynchronous.
Upvotes: 3
Reputation: 1503389
No, because in fact you're sleeping for 7 seconds before you print Waiting started
. Here's what happens:
If you change each Thread.Sleep
to
await Task.Delay(...);
then you'll see what you expect. The new flow will be:
It's really important to understand that until an async method hits the first await
where it actually needs to pause (because the thing it's awaiting hasn't completed), it executes synchronously. It's not like calling an async method splits off into a different thread.
Upvotes: 5