You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

58 regels
1.7 KiB

  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using MQTTnet.Core.Exceptions;
  5. namespace MQTTnet.Core.Internal
  6. {
  7. public static class TaskExtensions
  8. {
  9. public static Task TimeoutAfter(this Task task, TimeSpan timeout)
  10. {
  11. return TimeoutAfter(task.ContinueWith(t => 0), timeout);
  12. }
  13. public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
  14. {
  15. using (var cancellationTokenSource = new CancellationTokenSource())
  16. {
  17. var tcs = new TaskCompletionSource<TResult>();
  18. cancellationTokenSource.Token.Register(() =>
  19. {
  20. tcs.TrySetCanceled();
  21. });
  22. try
  23. {
  24. #pragma warning disable 4014
  25. task.ContinueWith(t =>
  26. #pragma warning restore 4014
  27. {
  28. if (t.IsFaulted)
  29. {
  30. tcs.TrySetException(t.Exception);
  31. }
  32. if (t.IsCompleted)
  33. {
  34. tcs.TrySetResult(t.Result);
  35. }
  36. }, cancellationTokenSource.Token);
  37. cancellationTokenSource.CancelAfter(timeout);
  38. return await tcs.Task;
  39. }
  40. catch (TaskCanceledException)
  41. {
  42. throw new MqttCommunicationTimedOutException();
  43. }
  44. catch (Exception e)
  45. {
  46. throw new MqttCommunicationException(e);
  47. }
  48. }
  49. }
  50. }
  51. }