C# Use async/await on UdpClient Receive

11.1k views Asked by At

The following code uses Task to receive asyncronously and shows the received result in the console:

private void ReceiveMessage()
{
    Task.Run(async() => 
    {
         using(var udpClient = new UdpClient(15000))
         {
             while(true)
             {
                 var receivedResult = await udpClient.ReceiveAsync();
                 Console.Write(Encoding.ASCII.GetString(receivedResult.Buffer));
             }
         }
    });
}

I want to learn how to use async/await functions so I would like to know how to make the function ReceiveMessage() asynchronously by using async/await?

3

There are 3 answers

2
René Vogt On BEST ANSWER

If you want the whole method to be awaitable, simply change it to that:

private async Task ReceiveMessage()
{
     using(var udpClient = new UdpClient(15000))
     {
         while(true)
         {
             var receivedResult = await udpClient.ReceiveAsync();
             Console.Write(Encoding.ASCII.GetString(receivedResult.Buffer));
         }
     }
}

You don't need Task.Run() anymore, which would use a thread. That thread is not needed. The method now returns to the caller while awaiting ReceiveAsync().
When ReceiveAsync() finishes, the method is (eventually) resumed at Console.WriteLine().

4
Trickzter On

Simply add another async/await to your function:

private async void receiveMessage()
{
    await Task.Run(async() => 
    {
         using(var udpClient = new UdpClient(15000))
         {
             while(true)
             {
                 var receivedResult = await udpClient.ReceiveAsync();
                 Console.Write(Encoding.ASCII.GetString(receivedResult.Buffer));
             }
         }
    });
}

If you want to write a method being awaitable, return a task:

private Task foo(){
    Task doStuff = new Task(() => {});
    doStuff.Start();
    return doStuff;
};

//Another method
private async void bar()
{
    await foo();
}

Update: As mentioned below, you do really not need the execution of that task on a thread inside the thread pool. It's not wrong, but useless. For better usage, you can use:

private async void receiveMessage()
{
     using(var udpClient = new UdpClient(15000))
     {
         while(true)
         {
             var receivedResult = await udpClient.ReceiveAsync();
             Console.Write(Encoding.ASCII.GetString(receivedResult.Buffer));
         }
     }
}
0
Stuart On

The code you have is valid if you want it to be fire and forget, listening on a separate thread. If you not want this, I would remove the Task.Run and be sure to return a Task in your method, like this:

private async Task ReceiveMessage()
{
    using (var udpClient = new UdpClient(15000))
    {
        while (true)
        {
            var receivedResult = await udpClient.ReceiveAsync();
            Console.Write(Encoding.ASCII.GetString(receivedResult.Buffer));
        }
    }
}