According to MSDN, async
and await
do not create new threads:
The
async
andawait
keywords don't cause additional threads to be created.
With this in mind, I'm having difficulty understanding control flow of some simple programs. My complete example is below. Note that it requires the Dataflow library, which you can install from NuGet.
using System;
using System.Threading.Tasks.Dataflow;
namespace TaskSandbox
{
class Program
{
static void Main(string[] args)
{
BufferBlock<int> bufferBlock = new BufferBlock<int>();
Consume(bufferBlock);
Produce(bufferBlock);
Console.ReadLine();
}
static bool touched;
static void Produce(ITargetBlock<int> target)
{
for (int i = 0; i < 5; i++)
{
Console.Error.WriteLine("Producing " + i);
target.Post(i);
Console.Error.WriteLine("Performing intensive computation");
touched = false;
for (int j = 0; j < 100000000; j++)
;
Console.Error.WriteLine("Finished intensive computation. Touched: " + touched);
}
target.Complete();
}
static async void Consume(ISourceBlock<int> source)
{
while (await source.OutputAvailableAsync())
{
touched = true;
int received = source.Receive();
Console.Error.WriteLine("Received " + received);
}
}
}
}
Output:
Producing 0
Performing intensive computation
Received 0
Finished intensive computation. Touched: True
Producing 1
Performing intensive computation
Received 1
Finished intensive computation. Touched: True
Producing 2
Performing intensive computation
Received 2
Finished intensive computation. Touched: False
Producing 3
Performing intensive computation
Received 3
Finished intensive computation. Touched: False
Producing 4
Performing intensive computation
Received 4
Finished intensive computation. Touched: True
This seems to indicate that Consume
is given control while the for
loop is running, as the OutputAvailableAsync
task completes:
for (int j = 0; j < 100000000; j++)
;
This would be unsurprising in a threaded model. But if no additional threads are involved, how can Produce
yield control in the middle of the for
loop?
if no additional threads are involved, how can Produce yield control in the middle of the for loop?
Who said no additional threads are involved? The fact that you stated was:
The async and await keywords don't cause additional threads to be created.
Which is absolutely true. Your program includes the fragments
target.Post(i);
await source.OutputAvailableAsync())
My guess would be that the call to target.Post(i)
or source.OutputAvailableAsync()
created a thread. The await
doesn't produce a thread; all the await
does is assigns the remainder of the method as the continuation of the task returned by the call and then returns control to the caller. If that task spawned a thread to do its work, that's it's business.
await
is just another control flow; a very complicated control flow, to be sure, but a control flow nevertheless. It's not a syntactic sugar for creating threads; it's a syntactic sugar for assigning a continuation to a task.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With