選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 

79 行
2.4 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. if (task == null) throw new ArgumentNullException(nameof(task));
  12. using (var timeoutCts = new CancellationTokenSource())
  13. {
  14. try
  15. {
  16. var timeoutTask = Task.Delay(timeout, timeoutCts.Token);
  17. var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false);
  18. if (finishedTask == timeoutTask)
  19. {
  20. throw new MqttCommunicationTimedOutException();
  21. }
  22. if (task.IsCanceled)
  23. {
  24. throw new TaskCanceledException();
  25. }
  26. if (task.IsFaulted)
  27. {
  28. throw new MqttCommunicationException(task.Exception?.GetBaseException());
  29. }
  30. }
  31. finally
  32. {
  33. timeoutCts.Cancel();
  34. }
  35. }
  36. }
  37. public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
  38. {
  39. if (task == null) throw new ArgumentNullException(nameof(task));
  40. using (var timeoutCts = new CancellationTokenSource())
  41. {
  42. try
  43. {
  44. var timeoutTask = Task.Delay(timeout, timeoutCts.Token);
  45. var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false);
  46. if (finishedTask == timeoutTask)
  47. {
  48. throw new MqttCommunicationTimedOutException();
  49. }
  50. if (task.IsCanceled)
  51. {
  52. throw new TaskCanceledException();
  53. }
  54. if (task.IsFaulted)
  55. {
  56. throw new MqttCommunicationException(task.Exception.GetBaseException());
  57. }
  58. return task.Result;
  59. }
  60. finally
  61. {
  62. timeoutCts.Cancel();
  63. }
  64. }
  65. }
  66. }
  67. }