我试图玩.NET Core,并想连接到本地的TCP服务器。 当我同步执行时没有问题(请参阅第一个Connect
方法)。 当我尝试使用async
/ await
(请参阅第二个ConnectAsync
方法)来做到这一点时,它变得疯狂并且几乎不可开发。 如果我正确地使用TcpClient,我不是起诉,因为网上还没有很多例子。 调用TcpClient.GetStream
后,确切的问题开始。 我试图debugging到禁用JustMyCode
和Visual Studio代码中的All exceptions
checkbox – 但它只是不跳转到TcpClient.GetStream
。
async
模式下的观察
TcpClient.GetStream
崩溃 Console.WriteLine
出现在控制台有时) The program 'bla' has exited with code 0 (0x00000000)
) 我的系统/项目设置:
码:
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虚拟机关闭。