我正在使用.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);
}
}
答案 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
,我在文章中粘贴摘录以供快速参考
- 醇>
如果调用者不期望它们是异步的,则异步void方法可能会造成严重破坏。当返回类型为Task时,调用者知道它 处理未来的运作;当返回类型为void时, 调用者可能会认为该方法在返回时已完成。 这个问题可能会以许多意想不到的方式出现。
- 异步无效方法的异常无法通过Catch捕获