CancellationTokenExtensions.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. using System;
  2. using System.Threading;
  3. namespace ETModel
  4. {
  5. public static class CancellationTokenExtensions
  6. {
  7. private static readonly Action<object> cancellationTokenCallback = Callback;
  8. public static (ETTask, CancellationTokenRegistration) ToETTask(this CancellationToken cts)
  9. {
  10. if (cts.IsCancellationRequested)
  11. {
  12. return (ETTask.FromCanceled(cts), default);
  13. }
  14. var promise = new ETTaskCompletionSource<AsyncUnit>();
  15. return (promise.Task, cts.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
  16. }
  17. private static void Callback(object state)
  18. {
  19. var promise = (ETTaskCompletionSource<AsyncUnit>) state;
  20. promise.TrySetResult(AsyncUnit.Default);
  21. }
  22. public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
  23. {
  24. bool restoreFlow = false;
  25. if (!ExecutionContext.IsFlowSuppressed())
  26. {
  27. ExecutionContext.SuppressFlow();
  28. restoreFlow = true;
  29. }
  30. try
  31. {
  32. return cancellationToken.Register(callback, false);
  33. }
  34. finally
  35. {
  36. if (restoreFlow)
  37. {
  38. ExecutionContext.RestoreFlow();
  39. }
  40. }
  41. }
  42. public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken,
  43. Action<object> callback, object state)
  44. {
  45. bool restoreFlow = false;
  46. if (!ExecutionContext.IsFlowSuppressed())
  47. {
  48. ExecutionContext.SuppressFlow();
  49. restoreFlow = true;
  50. }
  51. try
  52. {
  53. return cancellationToken.Register(callback, state, false);
  54. }
  55. finally
  56. {
  57. if (restoreFlow)
  58. {
  59. ExecutionContext.RestoreFlow();
  60. }
  61. }
  62. }
  63. }
  64. }