3

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?

FinFon
  • 85
  • 1
  • 2
  • 8

3 Answers3

6

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().

René Vogt
  • 43,056
  • 14
  • 77
  • 99
0

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));
         }
     }
}
Trickzter
  • 471
  • 3
  • 14
  • 3
    The `Task.Run()` is unnecessarily using a thread from the thread pool. Since `ReceiveAsync()` is already `await`ed, this is a waste of resources. – René Vogt Jan 02 '17 at 14:35
  • That's totally correct, but not point of discussion here. He was only asking for a way to make it working asynchronously and I just completed the code. But you are right sir. – Trickzter Jan 02 '17 at 14:38
  • 2
    The purpose of SO is to give helpful answers that can help future readers, too. Of course you answered OP's immediate question, but even he states that he _wants to learn_. Showing bad code as a good example has a little smell. – René Vogt Jan 02 '17 at 14:40
  • @RenéVogt agreed. – Trickzter Jan 02 '17 at 14:44
0

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));
        }
    }
}
Stuart
  • 5,358
  • 19
  • 28