Advertisement
Guest User

Untitled

a guest
Dec 8th, 2016
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.33 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5.  
  6. namespace AbCap.EnterpriseDevelopment.Common
  7. {
  8. /// <summary>
  9. /// Async Helpers
  10. /// </summary>
  11. public static class AsyncHelpers
  12. {
  13. /// <summary>
  14. /// Execute's an async Task<T> method which has a void return value synchronously
  15. /// </summary>
  16. /// <param name="task">Task<T> method to execute</param>
  17. public static void RunSync(Func<Task> task)
  18. {
  19. var oldContext = SynchronizationContext.Current;
  20. var synch = new ExclusiveSynchronizationContext();
  21. SynchronizationContext.SetSynchronizationContext(synch);
  22. synch.Post(async _ =>
  23. {
  24. try
  25. {
  26. await task();
  27. }
  28. catch (Exception e)
  29. {
  30. synch.InnerException = e;
  31. throw;
  32. }
  33. finally
  34. {
  35. synch.EndMessageLoop();
  36. }
  37. }, null);
  38. synch.BeginMessageLoop();
  39.  
  40. SynchronizationContext.SetSynchronizationContext(oldContext);
  41. }
  42.  
  43. /// <summary>
  44. /// Execute's an async Task<T> method which has a T return type synchronously
  45. /// </summary>
  46. /// <typeparam name="T">Return Type</typeparam>
  47. /// <param name="task">Task<T> method to execute</param>
  48. /// <returns></returns>
  49. public static T RunSync<T>(Func<Task<T>> task)
  50. {
  51. var oldContext = SynchronizationContext.Current;
  52. var synch = new ExclusiveSynchronizationContext();
  53. SynchronizationContext.SetSynchronizationContext(synch);
  54. T ret = default(T);
  55. synch.Post(async _ =>
  56. {
  57. try
  58. {
  59. ret = await task();
  60. }
  61. catch (Exception e)
  62. {
  63. synch.InnerException = e;
  64. throw;
  65. }
  66. finally
  67. {
  68. synch.EndMessageLoop();
  69. }
  70. }, null);
  71. synch.BeginMessageLoop();
  72. SynchronizationContext.SetSynchronizationContext(oldContext);
  73. return ret;
  74. }
  75.  
  76. private class ExclusiveSynchronizationContext : SynchronizationContext
  77. {
  78. private bool done;
  79. public Exception InnerException { get; set; }
  80. private readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false);
  81.  
  82. private readonly Queue<Tuple<SendOrPostCallback, object>> items =
  83. new Queue<Tuple<SendOrPostCallback, object>>();
  84.  
  85. public override void Send(SendOrPostCallback d, object state)
  86. {
  87. throw new NotSupportedException("We cannot send to our same thread");
  88. }
  89.  
  90. public override void Post(SendOrPostCallback d, object state)
  91. {
  92. lock (items)
  93. {
  94. items.Enqueue(Tuple.Create(d, state));
  95. }
  96. workItemsWaiting.Set();
  97. }
  98.  
  99. public void EndMessageLoop()
  100. {
  101. Post(_ => done = true, null);
  102. }
  103.  
  104. public void BeginMessageLoop()
  105. {
  106. while (!done)
  107. {
  108. Tuple<SendOrPostCallback, object> task = null;
  109. lock (items)
  110. {
  111. if (items.Count > 0)
  112. {
  113. task = items.Dequeue();
  114. }
  115. }
  116. if (task != null)
  117. {
  118. task.Item1(task.Item2);
  119. if (InnerException != null) // the method threw an exeption
  120. {
  121. throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException);
  122. }
  123. }
  124. else
  125. {
  126. workItemsWaiting.WaitOne();
  127. }
  128. }
  129. }
  130.  
  131. public override SynchronizationContext CreateCopy()
  132. {
  133. return this;
  134. }
  135. }
  136. }
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement