I am playing with the async/await in the C# and while I think that I understand most of the concepts, I can not explain why the code line "var rxres = await ..." first time runs on my UDP thread, and after further receptions of the packets runs on the worker thread. As far as I understand, I am not "yielding" back to the thread function and it is still alive and so all invocations of ReceiveAsync should run on the thread I created.
static void Main(string[] args)
{
var ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
var udpThread = new Thread(async () =>
{
ListenUdpAsync().Wait();
});
udpThread.Name = "UDP THREAD";
udpThread.Start();
ewh.WaitOne();
}
static public async Task ListenUdpAsync()
{
var localPort = 5555;
var localBind = new IPEndPoint(IPAddress.Any, localPort);
using (var udpc = new UdpClient(localBind))
{
while(true)
{
var rxres = await udpc.ReceiveAsync();
Console.WriteLine("Rx From: " + rxres.RemoteEndPoint);
Console.WriteLine("Rx Data: " + Encoding.ASCII.GetString(rxres.Buffer));
}
}
}
I am not "yielding" back to the thread function
The method yields once hitting await udpc.ReceiveAsync(), that is how async-await works. ListenAsync itself synchronously blocks, but since there is no sync context that comes into play, the continuation is able to marshal itself onto an arbitrary thread pool thread.
so all invocations of ReceiveAsync should run on the thread I created.
Not really. Generally, when you're running inside a console application, it uses the default TaskScheduler, which internally uses the thread pool to execute continuations on an arbitrary threadpool thread. Ones ReceiveAsync() completes, its continuation needs to be scheduled somewhere, and that place is on the thread pool.
On a side note - there is no reason to use the async modifier on the delegate, as you're not awaiting anything inside, but synchronously blocking.
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