.NET核心:使用asynchronous时TcpClient.GetStream崩溃

我试图玩.NET Core,并想连接到本地的TCP服务器。 当我同步执行时没有问题(请参阅第一个Connect方法)。 当我尝试使用async / await (请参阅第二个ConnectAsync方法)来做到这一点时,它变得疯狂并且几乎不可开发。 如果我正确地使用TcpClient,我不是起诉,因为网上还没有很多例子。 调用TcpClient.GetStream后,确切的问题开始。 我试图debugging到禁用JustMyCode和Visual Studio代码中的All exceptionscheckbox – 但它只是不跳转到TcpClient.GetStream

async模式下的观察

  • 有时它直接在TcpClient.GetStream崩溃
  • 有时它调用函数返回后崩溃(我看到最后Console.WriteLine出现在控制台有时)
  • 程序立即停止,debugging器closures(不会抛出exception)
  • 返回代码始终为零( The program 'bla' has exited with code 0 (0x00000000)

我的系统/项目设置:

  • Windows 10 64bit(教育)
  • .NET核心1.0.0
  • 控制台程序
  • 本地TCP服务器,因此没有连接问题
  • Visual Studio代码(不应该)

码:

 public class Connection { private TcpClient _client; public NetworkStream Stream { get; private set; } private CancellationTokenSource _token; public Connection() { _token = new CancellationTokenSource(); _client = new TcpClient(); } public void Connect(string host, int port) { Console.WriteLine("connecting..."); _client.ConnectAsync(host, port); Console.WriteLine("connected!"); while (!_client.Connected) { Thread.Sleep(20); } Console.WriteLine("getting stream..."); Stream = _client.GetStream(); // works because of Thread.Sleep above until the socket is connected Console.WriteLine("got stream!"); } public async Task ConnectAsync(string host, int port) { Console.WriteLine("connecting..."); await _client.ConnectAsync(host, port); Console.WriteLine("connected!"); // I know I could check for TcpClient.Connected but I see in debugger that the property is True Console.WriteLine("getting stream..."); Stream = _client.GetStream(); // crash in GetStream / crash after this function has returned Console.WriteLine("got stream!"); // sometimes this is going to be printed, sometimes not } // ... } 

您所描述的问题指向您的应用程序死亡的主线程。 要正确识别这个问题,必须查看整个应用程序和在任何特定时刻处于活动状态的线程。

但是,例如,一个简单的控制台应用程序终止主子被终止。 取决于你如何调用你的ConnectAsync函数,你可能缺少一些确保主循环没有终止的东西。 确保您的主入口点不是async函数,因为一旦它达到第一个await ,它就会终止。

两种方法之间的主要区别在于, ConnectAsync方法实际上很可能切换线程,并在另一个线程中执行第二部分,而不像Connect函数那样阻塞它所调用的线程。

它解释了你正在描述的行为。 一段时间后

 await _client.ConnectAsync(host, port); 

行被执行,应用程序的主循环终止并导致整个.NET虚拟机关闭。