The*_*gth 9 c# sockets windows async-await .net-core
我尝试使用.NET Core并希望连接到本地TCP服务器.当我同步进行时没有问题(参见第Connect一种方法).当我尝试使用async/ await(参见第二种ConnectAsync方法)时,它会变得疯狂并且几乎无法辨认.如果我正确使用TcpClient,我不会起诉,因为网上没有那么多的例子.调用后确切的问题开始了TcpClient.GetStream.我尝试使用Visual Studio Code中的JustMyCode禁用和All exceptions复选框进行调试- 但它不会跳转到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
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
您描述的问题指向应用程序死亡的主线程.要正确识别该问题,必须查看整个应用程序以及在任何给定时刻处于活动状态的线程.
但是,例如,一个简单的控制台应用程序一旦主子终止就终止.根据您调用ConnectAsync函数的方式,您可能缺少确保主循环不会终止的内容.确保您的主入口点不是一个async函数,因为它将在它第一次到达时立即终止await.
两种方法之间发生的主要区别在于该ConnectAsync方法实际上非常可能地切换线程并在不同的线程中执行第二部分,而不像Connect函数那样阻塞它被调用的线程.
它准确地解释了您描述的行为.一段时间之后
await _client.ConnectAsync(host, port);
Run Code Online (Sandbox Code Playgroud)
line执行应用程序的主循环终止并导致整个.NET VM关闭.