Why does asynchronous code run on a worker thread in C #

I'm playing around with async / await in C #, and while I think I understand most of the concepts, I can't explain why the line of code "var rxres = await ..." is first run on my UDP branch, and after further tricks a worker thread is running. As far as I understand, I am not returning to the thread function and it is still alive, so all calls to ReceiveAsync must be made 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));
            }
        }
    }

      

+3


source to share


1 answer


I am not returning to the thread function

The method gives a single click await udpc.ReceiveAsync()

, this is how async-await works. ListenAsync

itself blocks synchronously, but since there is no synchronous context to come into play, a continuation can march to an arbitrary thread of the thread pool.

so all calls to ReceiveAsync must be done on the thread I created.



Not really. Typically when you are running in a console application, it uses the default TaskScheduler

, which internally uses the thread pool to execute continuations on an arbitrary threadpool. Ones ReceiveAsync()

finishes, its continuation needs to be scheduled somewhere, and that place is in the thread pool.

On a side note - there is no reason to use a modifier async

on a delegate, since you don't expect anything internally, but block synchronously.

+4


source







All Articles