I tried to play with .NET Core and want to connect to a local TCP server. No issues when I do it synchronously (see first Connect
method). When I try to do it with async
/await
(see second ConnectAsync
method), it goes crazy and nearly undebuggable. I'm not sue if I use TcpClient correctly since there are not as many examples yet available on the web. The exact problems start after calling TcpClient.GetStream
. I tried to debug into this with JustMyCode
disabled and All exceptions
checkbox in Visual Studio Code - but it just don't jumps into TcpClient.GetStream
.
Observations in async
mode:
TcpClient.GetStream
directlyConsole.WriteLine
appears in console sometimes)The program 'bla' has exited with code 0 (0x00000000)
)My system/project setup:
Code:
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
}
// ...
}
The problem you are describing points to the main thread of your application dying. To identify that problem correctly one has to look at the entire applications and the threads that are active at any given moment.
But for example a simple console application terminates as soon as the main sub is terminated. Depending on how you call your ConnectAsync
function you may lack something that ensures that the main loop is not terminated. Make sure that your main entry point is not a async
function because this will terminate as soon as it reaches it's first await
.
The main difference that happens between your two methods is that the ConnectAsync
method actually switches threads very likely and executes the second part in a different thread, not blocking the thread it was called in like the Connect
function does.
It explains exactly the behaviour your are describing. Some time after the
await _client.ConnectAsync(host, port);
line is executed the main loop of your application terminates and causes the entire .NET VM to shut down.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With