DispatcherSchedulerTest.cs 7.9 KB

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