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.
 
 
 
 

59 line
2.2 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(Func<CancellationToken, Task> action, TimeSpan timeout, CancellationToken cancellationToken)
  10. {
  11. if (action == null) throw new ArgumentNullException(nameof(action));
  12. using (var timeoutCts = new CancellationTokenSource(timeout))
  13. using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(timeoutCts.Token, cancellationToken))
  14. {
  15. try
  16. {
  17. await action(linkedCts.Token).ConfigureAwait(false);
  18. }
  19. catch (OperationCanceledException exception)
  20. {
  21. var timeoutReached = timeoutCts.IsCancellationRequested && !cancellationToken.IsCancellationRequested;
  22. if (timeoutReached)
  23. {
  24. throw new MqttCommunicationTimedOutException(exception);
  25. }
  26. throw;
  27. }
  28. }
  29. }
  30. public static async Task<TResult> TimeoutAfter<TResult>(Func<CancellationToken, Task<TResult>> action, TimeSpan timeout, CancellationToken cancellationToken)
  31. {
  32. if (action == null) throw new ArgumentNullException(nameof(action));
  33. using (var timeoutCts = new CancellationTokenSource(timeout))
  34. using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(timeoutCts.Token, cancellationToken))
  35. {
  36. try
  37. {
  38. return await action(linkedCts.Token).ConfigureAwait(false);
  39. }
  40. catch (OperationCanceledException exception)
  41. {
  42. var timeoutReached = timeoutCts.IsCancellationRequested && !cancellationToken.IsCancellationRequested;
  43. if (timeoutReached)
  44. {
  45. throw new MqttCommunicationTimedOutException(exception);
  46. }
  47. throw;
  48. }
  49. }
  50. }
  51. }
  52. }