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