+
+ [Test]
+ public void Wait_SetConcurrent ()
+ {
+ for (int i = 0; i < 10000; ++i) {
+ var mre = new ManualResetEventSlim ();
+ bool b = true;
+
+ ThreadPool.QueueUserWorkItem (delegate {
+ mre.Set ();
+ });
+
+ ThreadPool.QueueUserWorkItem (delegate {
+ b &= mre.Wait (1000);
+ });
+
+ Assert.IsTrue (mre.Wait (1000), i.ToString ());
+ Assert.IsTrue (b, i.ToString ());
+ }
+ }
+
+ [Test]
+ public void Wait_DisposeWithCancel ()
+ {
+ var token = new CancellationTokenSource ();
+ ThreadPool.QueueUserWorkItem (delegate {
+ Thread.Sleep (10);
+ mre.Dispose ();
+ token.Cancel ();
+ });
+
+ try {
+ mre.Wait (10000, token.Token);
+ Assert.Fail ("#0");
+ } catch (OperationCanceledException e) {
+ }
+ }
+
+ [Test]
+ public void Wait_Expired ()
+ {
+ Assert.IsFalse (mre.Wait (10));
+ }
+
+ [Test, ExpectedException (typeof (ObjectDisposedException))]
+ public void WaitAfterDisposeTest ()
+ {
+ mre.Dispose ();
+ mre.Wait ();
+ }
+
+ [Test]
+ public void SetAfterDisposeTest ()
+ {
+ ParallelTestHelper.Repeat (delegate {
+ Exception disp = null, setting = null;
+
+ CountdownEvent evt = new CountdownEvent (2);
+ CountdownEvent evtFinish = new CountdownEvent (2);
+
+ ThreadPool.QueueUserWorkItem (delegate {
+ try {
+ evt.Signal ();
+ evt.Wait (1000);
+ mre.Dispose ();
+ } catch (Exception e) {
+ disp = e;
+ }
+ evtFinish.Signal ();
+ });
+ ThreadPool.QueueUserWorkItem (delegate {
+ try {
+ evt.Signal ();
+ evt.Wait (1000);
+ mre.Set ();
+ } catch (Exception e) {
+ setting = e;
+ }
+ evtFinish.Signal ();
+ });
+
+ bool bb = evtFinish.Wait (1000);
+ if (!bb)
+ Assert.AreEqual (true, evtFinish.IsSet);
+
+ Assert.IsTrue (bb, "#0");
+ Assert.IsNull (disp, "#1");
+ Assert.IsNull (setting, "#2");
+
+ evt.Dispose ();
+ evtFinish.Dispose ();
+ });
+ }
+
+ [Test]
+ public void WaitHandle_Initialized ()
+ {
+ var mre = new ManualResetEventSlim (true);
+ Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#1");
+ mre.Reset ();
+ Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#2");
+ Assert.AreEqual (mre.WaitHandle, mre.WaitHandle, "#3");
+ }
+
+ [Test]
+ public void WaitHandle_NotInitialized ()
+ {
+ var mre = new ManualResetEventSlim (false);
+ Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#1");
+ mre.Set ();
+ Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#2");
+ }
+
+ [Test]
+ public void WaitHandleConsistencyTest ()
+ {
+ var mre = new ManualResetEventSlim ();
+ mre.WaitHandle.WaitOne (0);
+
+ for (int i = 0; i < 10000; i++) {
+ int count = 2;
+ SpinWait wait = new SpinWait ();
+
+ ThreadPool.QueueUserWorkItem (_ => { mre.Set (); Interlocked.Decrement (ref count); });
+ ThreadPool.QueueUserWorkItem (_ => { mre.Reset (); Interlocked.Decrement (ref count); });
+
+ while (count > 0)
+ wait.SpinOnce ();
+ Assert.AreEqual (mre.IsSet, mre.WaitHandle.WaitOne (0));
+ }
+ }
+
+ [Test]
+ public void WaitWithCancellationTokenAndNotImmediateSetTest ()
+ {
+ var mres = new ManualResetEventSlim ();
+ var cts = new CancellationTokenSource ();
+ ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); mres.Set (); });
+ Assert.IsTrue (mres.Wait (TimeSpan.FromSeconds (10), cts.Token), "Wait returned false despite event was set.");
+ }
+
+ [Test]
+ public void WaitWithCancellationTokenAndCancel ()
+ {
+ var mres = new ManualResetEventSlim ();
+ var cts = new CancellationTokenSource ();
+ ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); cts.Cancel (); });
+ try {
+ mres.Wait (TimeSpan.FromSeconds (10), cts.Token);
+ Assert.Fail ("Wait did not throw an exception despite cancellation token was cancelled.");
+ } catch (OperationCanceledException) {
+ }
+ }
+
+ [Test]
+ public void WaitWithCancellationTokenAndTimeout ()
+ {
+ var mres = new ManualResetEventSlim ();
+ var cts = new CancellationTokenSource ();
+ Assert.IsFalse (mres.Wait (TimeSpan.FromSeconds (1), cts.Token), "Wait returned true despite timeout.");
+ }
+
+ [Test]
+ public void Dispose ()
+ {
+ var mre = new ManualResetEventSlim (false);
+ mre.Dispose ();
+ Assert.IsFalse (mre.IsSet, "#0a");
+
+ try {
+ mre.Reset ();
+ Assert.Fail ("#1");
+ } catch (ObjectDisposedException) {
+ }
+
+ mre.Set ();
+
+ try {
+ mre.Wait (0);
+ Assert.Fail ("#3");
+ } catch (ObjectDisposedException) {
+ }
+
+ try {
+ var v = mre.WaitHandle;
+ Assert.Fail ("#4");
+ } catch (ObjectDisposedException) {
+ }
+ }
+
+ [Test]
+ public void Dispose_Double ()
+ {
+ var mre = new ManualResetEventSlim ();
+ mre.Dispose ();
+ mre.Dispose ();
+ }