25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

56 lines
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. cancellationTokenSource.CancelAfter(timeout);
  25. task.ContinueWith( t =>
  26. {
  27. if (t.IsFaulted)
  28. {
  29. tcs.TrySetException(t.Exception);
  30. }
  31. if (t.IsCompleted)
  32. {
  33. tcs.TrySetResult(t.Result);
  34. }
  35. }, cancellationTokenSource.Token );
  36. return await tcs.Task;
  37. }
  38. catch (TaskCanceledException)
  39. {
  40. throw new MqttCommunicationTimedOutException();
  41. }
  42. catch (Exception e)
  43. {
  44. throw new MqttCommunicationException(e);
  45. }
  46. }
  47. }
  48. }
  49. }