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
CodePudding user response:
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, i.e. 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.
CodePudding user response:
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;
}