using System; using System.Threading; using System.Threading.Tasks; using MQTTnet.Core.Exceptions; namespace MQTTnet.Core.Internal { public static class TaskExtensions { public static async Task TimeoutAfter( this Task task, TimeSpan timeout ) { using ( var cancellationTokenSource = new CancellationTokenSource() ) { try { var timeoutTask = Task.Delay(timeout, cancellationTokenSource.Token); var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false); if ( finishedTask == timeoutTask ) { throw new MqttCommunicationTimedOutException(); } if ( task.IsCanceled ) { throw new TaskCanceledException(); } if ( task.IsFaulted ) { throw new MqttCommunicationException( task.Exception.GetBaseException() ); } } finally { cancellationTokenSource.Cancel(); } } } public static async Task TimeoutAfter( this Task task, TimeSpan timeout ) { using ( var cancellationTokenSource = new CancellationTokenSource() ) { try { var timeoutTask = Task.Delay(timeout, cancellationTokenSource.Token); var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false); if ( finishedTask == timeoutTask ) { throw new MqttCommunicationTimedOutException(); } if ( task.IsCanceled ) { throw new TaskCanceledException(); } if ( task.IsFaulted ) { throw new MqttCommunicationException( task.Exception.GetBaseException() ); } return task.Result; } finally { cancellationTokenSource.Cancel(); } } } } }