1
0

DispatcherSchedulerTest.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. #if NET45
  5. using System;
  6. using System.Diagnostics;
  7. using System.Reactive.Concurrency;
  8. using System.Reactive.Disposables;
  9. using System.Threading;
  10. using System.Windows.Threading;
  11. using Microsoft.Reactive.Testing;
  12. using Xunit;
  13. namespace ReactiveTests.Tests
  14. {
  15. public class DispatcherSchedulerTest : TestBase
  16. {
  17. [Fact]
  18. public void Ctor_ArgumentChecking()
  19. {
  20. ReactiveAssert.Throws<ArgumentNullException>(() => new DispatcherScheduler(null));
  21. }
  22. [Fact]
  23. public void Current()
  24. {
  25. var d = DispatcherHelpers.EnsureDispatcher();
  26. var e = new ManualResetEvent(false);
  27. d.BeginInvoke(() =>
  28. {
  29. var c = DispatcherScheduler.Current;
  30. c.Schedule(() => { e.Set(); });
  31. });
  32. e.WaitOne();
  33. }
  34. [Fact]
  35. public void Current_None()
  36. {
  37. var e = default(Exception);
  38. var t = new Thread(() =>
  39. {
  40. try
  41. {
  42. var ignored = DispatcherScheduler.Current;
  43. }
  44. catch (Exception ex)
  45. {
  46. e = ex;
  47. }
  48. });
  49. t.Start();
  50. t.Join();
  51. Assert.True(e != null && e is InvalidOperationException);
  52. }
  53. [Fact]
  54. public void Dispatcher()
  55. {
  56. var disp = DispatcherHelpers.EnsureDispatcher();
  57. Assert.Same(disp.Dispatcher, new DispatcherScheduler(disp).Dispatcher);
  58. }
  59. [Fact]
  60. public void Now()
  61. {
  62. var disp = DispatcherHelpers.EnsureDispatcher();
  63. var res = new DispatcherScheduler(disp).Now - DateTime.Now;
  64. Assert.True(res.Seconds < 1);
  65. }
  66. [Fact]
  67. public void Schedule_ArgumentChecking()
  68. {
  69. var disp = DispatcherHelpers.EnsureDispatcher();
  70. var s = new DispatcherScheduler(disp);
  71. ReactiveAssert.Throws<ArgumentNullException>(() => s.Schedule(42, default(Func<IScheduler, int, IDisposable>)));
  72. ReactiveAssert.Throws<ArgumentNullException>(() => s.Schedule(42, TimeSpan.FromSeconds(1), default(Func<IScheduler, int, IDisposable>)));
  73. ReactiveAssert.Throws<ArgumentNullException>(() => s.Schedule(42, DateTimeOffset.Now, default(Func<IScheduler, int, IDisposable>)));
  74. }
  75. [Fact]
  76. [Asynchronous]
  77. public void Schedule()
  78. {
  79. var disp = DispatcherHelpers.EnsureDispatcher();
  80. RunAsync(evt =>
  81. {
  82. var id = Thread.CurrentThread.ManagedThreadId;
  83. var sch = new DispatcherScheduler(disp);
  84. sch.Schedule(() =>
  85. {
  86. Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
  87. disp.InvokeShutdown();
  88. evt.Set();
  89. });
  90. });
  91. }
  92. [Fact]
  93. public void ScheduleError()
  94. {
  95. var ex = new Exception();
  96. var id = Thread.CurrentThread.ManagedThreadId;
  97. var disp = DispatcherHelpers.EnsureDispatcher();
  98. var evt = new ManualResetEvent(false);
  99. disp.UnhandledException += (o, e) =>
  100. {
  101. #if NET45 || NET46
  102. Assert.Same(ex, e.Exception); // CHECK
  103. #else
  104. Assert.Same(ex, e.Exception.InnerException); // CHECK
  105. #endif
  106. evt.Set();
  107. e.Handled = true;
  108. };
  109. var sch = new DispatcherScheduler(disp);
  110. sch.Schedule(() => { throw ex; });
  111. evt.WaitOne();
  112. disp.InvokeShutdown();
  113. }
  114. [Fact]
  115. public void ScheduleRelative()
  116. {
  117. ScheduleRelative_(TimeSpan.FromSeconds(0.2));
  118. }
  119. [Fact]
  120. public void ScheduleRelative_Zero()
  121. {
  122. ScheduleRelative_(TimeSpan.Zero);
  123. }
  124. private void ScheduleRelative_(TimeSpan delay)
  125. {
  126. var evt = new ManualResetEvent(false);
  127. var id = Thread.CurrentThread.ManagedThreadId;
  128. var disp = DispatcherHelpers.EnsureDispatcher();
  129. var sch = new DispatcherScheduler(disp);
  130. sch.Schedule(delay, () =>
  131. {
  132. Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
  133. sch.Schedule(delay, () =>
  134. {
  135. Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
  136. evt.Set();
  137. });
  138. });
  139. evt.WaitOne();
  140. disp.InvokeShutdown();
  141. }
  142. [Fact]
  143. public void ScheduleRelative_Cancel()
  144. {
  145. var evt = new ManualResetEvent(false);
  146. var id = Thread.CurrentThread.ManagedThreadId;
  147. var disp = DispatcherHelpers.EnsureDispatcher();
  148. var sch = new DispatcherScheduler(disp);
  149. sch.Schedule(TimeSpan.FromSeconds(0.1), () =>
  150. {
  151. Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
  152. var d = sch.Schedule(TimeSpan.FromSeconds(0.1), () =>
  153. {
  154. Assert.True(false);
  155. evt.Set();
  156. });
  157. sch.Schedule(() =>
  158. {
  159. d.Dispose();
  160. });
  161. sch.Schedule(TimeSpan.FromSeconds(0.2), () =>
  162. {
  163. Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
  164. evt.Set();
  165. });
  166. });
  167. evt.WaitOne();
  168. disp.InvokeShutdown();
  169. }
  170. [Fact]
  171. public void SchedulePeriodic_ArgumentChecking()
  172. {
  173. var disp = DispatcherHelpers.EnsureDispatcher();
  174. var s = new DispatcherScheduler(disp);
  175. ReactiveAssert.Throws<ArgumentNullException>(() => s.SchedulePeriodic(42, TimeSpan.FromSeconds(1), default(Func<int, int>)));
  176. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => s.SchedulePeriodic(42, TimeSpan.FromSeconds(-1), x => x));
  177. }
  178. [Fact]
  179. public void SchedulePeriodic()
  180. {
  181. var evt = new ManualResetEvent(false);
  182. var id = Thread.CurrentThread.ManagedThreadId;
  183. var disp = DispatcherHelpers.EnsureDispatcher();
  184. var sch = new DispatcherScheduler(disp);
  185. var d = new SingleAssignmentDisposable();
  186. d.Disposable = sch.SchedulePeriodic(1, TimeSpan.FromSeconds(0.1), n =>
  187. {
  188. Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
  189. if (n == 3)
  190. {
  191. d.Dispose();
  192. sch.Schedule(TimeSpan.FromSeconds(0.2), () =>
  193. {
  194. Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
  195. evt.Set();
  196. });
  197. }
  198. if (n > 3)
  199. {
  200. Assert.True(false);
  201. }
  202. return n + 1;
  203. });
  204. evt.WaitOne();
  205. disp.InvokeShutdown();
  206. }
  207. }
  208. }
  209. #endif