C#await udpClient.ReceiveAsync()失败并终止程序

时间:2017-07-12 17:08:17

标签: c# async-await udpclient

我正在使用.NET 4.5.1运行C#控制台应用程序。当我运行以下函数时,下面的udpClient.ReceiveAsync()调用将无异常地终止程序。我该如何调试呢?

   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);
        }
    }

2 个答案:

答案 0 :(得分:5)

await udpClient.ReceiveAsync()的调用不是终止程序,也不是默默地失败。

鉴于这种情况正在发生,我假设你有这样的事情:

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

async void方法中,只要达到await调用,控制就会返回到父级,因此程序的流程如下:

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; 
        }
    }
}

所以程序因没有进一步的阻塞代码而结束。

为了使其按预期工作,请将代码更改为:

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

public async Task Run() { ... }

答案 1 :(得分:1)

不确定调用方法,但是根据给定的信息,我建议以下article具有围绕异步的最佳实践等待@Stephen Cleary

它说要避免async void,我在文章中粘贴摘录以供快速参考

  
      
  1. 如果调用者不期望它们是异步的,则异步void方法可能会造成严重破坏。当返回类型为Task时,调用者知道它   处理未来的运作;当返回类型为void时,   调用者可能会认为该方法在返回时已完成。   这个问题可能会以许多意想不到的方式出现。

         
        
    1. 异步无效方法的异常无法通过Catch捕获
    2.   
  2.