简体   繁体   中英

How to cancel an async connect method after X seconds in C#

I am creating a mqtt client in C# with the libray MQTTNet. I wan't my client to connect to a broker and stop after 1 second if doesn't succeed. Here is the function I made below.

private async Task TryConnect(MqttClientOptions options)
{
     CancellationTokenSource tokenSource = new CancellationTokenSource();
     mqttClient!.ConnectAsync(options, tokenSource.Token);
     await Task.Delay(1000);
     tokenSource.Cancel();
}

The method is working but it gives me a warning when I call the method ConnectAsync because I am not using an await operator before the call. And if I use the await operator the method will continue until it will raise an error.

Is there a way to do this without warnings? Because even if it is working I have the feeling that this is not the better way to do it and that there is a cleaner way.

Thank you for your help,

Emmanuel

You should probably use CancelAfter :

CancellationTokenSource tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromSeconds(1));
await mqttClient!.ConnectAsync(options, tokenSource.Token);

An alternative would be to store the task from connectAsync and await if after the cancel call.

Note that in either case you are not guaranteed that the connection will actually cancel, it entirely depends on the ConnectAsync -implementation. In some cases it might be approrpiate to use Task.WhenAny to await either the connection, or a Task.Delay, ie you do no longer care about the connection after the timeout. You should probably also catch OperationCancelledException , since that is the standard method to communicate that the operation actually was cancelled.

You can specify a timeout for a cancellation token:

var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));

If you're cancelling it like this you will need to catch a TaskCanceledException , but you can ignore the cancellation if you want.

private async Task TryConnect(MqttClientOptions options)
{
    var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));

    try
    {
        mqttClient!.ConnectAsync(options, tokenSource.Token);
    }

    catch (TaskCanceledException)
    {
        // Do nothing.
    }
}

Alternatively you could return a bool to indicate whether the connection was successful:

private async Task<bool> TryConnect(MqttClientOptions options)
{
    var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));

    try
    {
        mqttClient!.ConnectAsync(options, tokenSource.Token);
    }

    catch (TaskCanceledException)
    {
        return false;
    }

    return true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM