user6493962
user6493962

Reputation:

C# async - Exception not handled

This code here is not handling the Exception thrown, when it cant connect to the Server. Any Ideas why? Thanks!

public Form1()
        {
            InitializeComponent();
            StartClient();

        }
async private Task StartClient()
{
    try
    {
        await ConnectToServerAsync();
    }
    catch (System.Net.Sockets.SocketException)
    {
        MesssageBox.Show("TEST");
    }
}

private Task ConnectToServerAsync()
{
    return Task.Factory.StartNew(() => client.Connect(host, port));
}

Upvotes: 0

Views: 1154

Answers (2)

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131237

There are various problems with this code. First, using async void is only meant for event handlers. An async void method can't be awaited and any exceptions it throws can't be handled. Second, Task.Factory.StartNew(()=>client.Connect(host,port)) fakes asynchronous execution. It still blocks a thread. Asynchronous execution means that no thread is blocked while waiting for the operation to complete.

I assume you use TcpClient. This class already has a ConnectAsync method that connects in an asynchronous manner. You could simplify your code to this:

private async Task StartClient()
{
    try
    {
        await client.ConnectAsync(host,port);
    }
    catch (Exception exc)
    {
        MessageBox.Show(exc.ToString());
    }
}

If you want to start the client in response to a UI event, eg a button click, you'd write :

async void Button1_Click(object sender, EventArgs e)
{
    await StartClient();
}

or

async void Button1_Click(object sender, EventArgs e)
{
    try 
    {
        await StartClient();
        //Work with the client
    }
    catch(Exception exc)
    {
        MessageBox.Show(exc.ToString());
    }
}

Finally, use a logging library instead of MessageBox.Show, eg log4net so you don't lose exception messages due to threading issues.

Upvotes: 1

Yury Schkatula
Yury Schkatula

Reputation: 5369

The thing is: "async void" is very dangerous construct that should almost never appear in your production code. Async method is not a list of statements internally, it's kind of state machine that switches from one "await" statement to another, doing various things in-between while "awaiting". So, once you got an exception raised inside that state machine, you need special context to preserve the stack trace etc. Void methods do not provide such a context. Return Task or Task<something> instead.

As a further reading, I could recommend Phil Haack's very nice blogpost: http://haacked.com/archive/2014/11/11/async-void-methods/

Upvotes: 1

Related Questions