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.
 
 
 
 

75 regels
2.3 KiB

  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using MQTTnet.Exceptions;
  5. namespace MQTTnet.Internal
  6. {
  7. public static class TaskExtensions
  8. {
  9. public static async Task TimeoutAfter(this Task task, TimeSpan timeout)
  10. {
  11. using (var cancellationTokenSource = new CancellationTokenSource())
  12. {
  13. try
  14. {
  15. var timeoutTask = Task.Delay(timeout, cancellationTokenSource.Token);
  16. var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false);
  17. if (finishedTask == timeoutTask)
  18. {
  19. throw new MqttCommunicationTimedOutException();
  20. }
  21. if (task.IsCanceled)
  22. {
  23. throw new TaskCanceledException();
  24. }
  25. if (task.IsFaulted)
  26. {
  27. throw new MqttCommunicationException(task.Exception.GetBaseException());
  28. }
  29. }
  30. finally
  31. {
  32. cancellationTokenSource.Cancel();
  33. }
  34. }
  35. }
  36. public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
  37. {
  38. using (var cancellationTokenSource = new CancellationTokenSource())
  39. {
  40. try
  41. {
  42. var timeoutTask = Task.Delay(timeout, cancellationTokenSource.Token);
  43. var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false);
  44. if (finishedTask == timeoutTask)
  45. {
  46. throw new MqttCommunicationTimedOutException();
  47. }
  48. if (task.IsCanceled)
  49. {
  50. throw new TaskCanceledException();
  51. }
  52. if (task.IsFaulted)
  53. {
  54. throw new MqttCommunicationException(task.Exception.GetBaseException());
  55. }
  56. return task.Result;
  57. }
  58. finally
  59. {
  60. cancellationTokenSource.Cancel();
  61. }
  62. }
  63. }
  64. }
  65. }