empty
empty

Reputation: 5444

C# await udpClient.ReceiveAsync() fails and terminates program

I'm running a C# console application with .NET 4.5.1. When I run the following function the udpClient.ReceiveAsync() call below silently terminates the program with no exception. How do I debug this?

   public async void Run()
    {
        try
        {
            var armIpAddress = IPAddress.Parse("239.1.11.1");
            using (var udpClient = new UdpClient())
            {
                udpClient.ExclusiveAddressUse = false;
                var ipEndPoint = new IPEndPoint(IPAddress.Any, 12020);
                udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                udpClient.ExclusiveAddressUse = false;
                udpClient.Client.Bind(ipEndPoint);
                udpClient.JoinMulticastGroup(armIpAddress);

                while (true)
                {
                    var result = await udpClient.ReceiveAsync();
                    //...
                }
        }
        catch (Exception x)
        {
            Console.WriteLine(x.Message);
        }
    }

Upvotes: 1

Views: 877

Answers (2)

Camilo Terevinto
Camilo Terevinto

Reputation: 32058

The call to await udpClient.ReceiveAsync() is not terminating the program nor it is silently failing.

Given that this is happening, I assume you have something like this:

public static void Main(string[] args)
{
    ...
    Run();
}

In an async void method, control is returned to the parent as soon as an await call is reached, so the flow of the program would be something like:

public static void Main(string[] args)
{
    ...
    var armIpAddress = IPAddress.Parse("239.1.11.1");
    using (var udpClient = new UdpClient())
    {
        udpClient.ExclusiveAddressUse = false;
        .......

        while (true)
        {
            return; 
        }
    }
}

So the program ends due to no further blocking code.

For this to work as you would expect, change the code to this:

public static void Main(string[] args)
{
    ...
    Run().Wait();
}

public async Task Run() { ... }

Upvotes: 5

Jaya
Jaya

Reputation: 3911

Not sure about the calling method, but with the given infomation, I would suggest the following article that has best practices around async await by @Stephen Cleary

It says to avoid async void and I am pasting an excerpt here from the article for quick reference

  1. Async void methods can wreak havoc if the caller isn’t expecting them to be async. When the return type is Task, the caller knows it’s dealing with a future operation; when the return type is void, the caller might assume the method is complete by the time it returns. This problem can crop up in many unexpected ways.

    1. Exceptions from an Async Void Method Can’t Be Caught with Catch

Upvotes: 1

Related Questions