Example #1
0
        public void TestTimerStartAutoReset()
        {
            CountdownEvent cde = new CountdownEvent(1);
            int result = 0;
            _timer = new TestTimer(1);

            // Test defaults.
            Assert.Equal(1, _timer.Interval);
            Assert.True(_timer.AutoReset);

            _timer.AutoReset = false;
            _timer.Elapsed += (sender, e) => { result = ++result; cde.Signal(); };
            _timer.Start();

            Assert.True(_timer.Enabled);
            cde.Wait();

            // Only elapsed once.
            Assert.Equal(1, result);

            cde = new CountdownEvent(10);
            _timer.AutoReset = true;

            cde.Wait();
            cde.Dispose();

            _timer.Stop();
            // Atleast elapsed 10 times.
            Assert.True(result >= 10);
        }
Example #2
0
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         if (cntd != null)
         {
             cntd.Dispose();
             cntd = null;
         }
         postPhaseAction = null;
         cleaned         = true;
     }
 }
        public static void CancelBeforeWait()
        {
            CountdownEvent countdownEvent = new CountdownEvent(2);
            CancellationTokenSource cs = new CancellationTokenSource();
            cs.Cancel();
            CancellationToken ct = cs.Token;

            const int millisec = 100;
            TimeSpan timeSpan = new TimeSpan(100);
            string message = "CancelBeforeWait:  > Cancellation token does not match.";
            EnsureOperationCanceledExceptionThrown(() => countdownEvent.Wait(ct), ct, message);
            EnsureOperationCanceledExceptionThrown(() => countdownEvent.Wait(millisec, ct), ct, message);
            EnsureOperationCanceledExceptionThrown(() => countdownEvent.Wait(timeSpan, ct), ct, message);

            countdownEvent.Dispose();
        }
Example #4
0
        public void StartWithCallbackCalledTwice()
        {
            // arrange
            var loop = new EventLoop();
            var wait = new CountdownEvent(2);

            // act
            loop.Start(() => wait.Signal());
            loop.Start(() => wait.Signal());

            // assert
            Assert.That(() => wait.WaitHandle.WaitOne(100), Is.True);
            Assert.That(wait.CurrentCount, Is.EqualTo(0));

            // cleanup
            loop.Dispose();
            wait.Dispose();
        }
        public void SetInterval()
        {
            // arrange
            var loop = new EventLoop();
            loop.Start(() => { });
            var counter = new CountdownEvent(2);
            var callback = new Action(() => counter.Signal());
            var timeout = TimeSpan.FromMilliseconds(100);

            // act
            loop.SetInterval(callback, timeout);

            // assert
            Assert.That(counter.Wait(timeout + timeout + timeout), Is.True);

            // cleanup
            loop.Dispose();
            counter.Dispose();
        }
        public static bool CancelBeforeWait()
        {
            TestHarness.TestLog("* CountdownEventCancellationTests.CancelBeforeWait()");
            bool passed = true;

            
            CountdownEvent countdownEvent = new CountdownEvent(2);
            CancellationTokenSource cs = new CancellationTokenSource();
            cs.Cancel();
            CancellationToken ct = cs.Token;

            const int millisec = 100;
            TimeSpan timeSpan = new TimeSpan(100);

            passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(() => countdownEvent.Wait(ct), ct, "An OCE should have been thrown.");
            passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(() => countdownEvent.Wait(millisec, ct), ct, "An OCE should have been thrown.");
            passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(() => countdownEvent.Wait(timeSpan, ct), ct, "An OCE should have been thrown.");

            countdownEvent.Dispose();
            return passed;
        }
Example #7
0
//        public static Task CreateDocumentsAsync(Database db, int n)
//      {
//            return db.RunAsync((database)=>
//                {
//                    database.BeginTransaction();
//                    ApiTest.CreateDocuments(database, n);
//                    database.EndTransaction(true);
//                });
//      }

//          public static void CreateDocuments(Database db, int numberOfDocsToCreate)
//      {
//          //TODO should be changed to use db.runInTransaction
//          for (int i = 0; i < numberOfDocsToCreate; i++)
//          {
//                var properties = new Dictionary<String, Object>();
//                properties["testName"] = "testDatabase";
//                properties["sequence"] = i;
//              CreateDocumentWithProperties(db, properties);
//          }
//      }
//
//        public static Document CreateDocumentWithProperties(Database db, IDictionary<String, Object> properties)
//      {
//            var doc = db.CreateDocument();
//
//          Assert.IsNotNull(doc);
//          Assert.IsNull(doc.CurrentRevisionId);
//          Assert.IsNull(doc.CurrentRevision);
//          Assert.IsNotNull("Document has no ID", doc.Id);
//
//          // 'untitled' docs are no longer untitled (8/10/12)
//          try
//          {
//              doc.PutProperties(properties);
//          }
//          catch (Exception e)
//          {
//              Log.E(Tag, "Error creating document", e);
//                Assert.IsTrue( false, "can't create new document in db:" + db.Name +
//                    " with properties:" + properties.Aggregate(new StringBuilder(" >>> "), (str, kvp)=> { str.AppendFormat("'{0}:{1}' ", kvp.Key, kvp.Value); return str; }, str=>str.ToString()));
//          }
//
//          Assert.IsNotNull(doc.Id);
//          Assert.IsNotNull(doc.CurrentRevisionId);
//          Assert.IsNotNull(doc.UserProperties);
//          Assert.AreEqual(db.GetDocument(doc.Id), doc);
//
//          return doc;
//      }

        /// <exception cref="System.Exception"></exception>
        public void RunLiveQuery(String methodNameToCall)
        {
            var db = database;

            var doneSignal = new CountdownEvent(11); // FIXME.ZJG: Not sure why, but now Changed is only called once.

            // 11 corresponds to startKey = 23; endKey = 33
            // run a live query
            var view = db.GetView("vu");
            view.SetMap((document, emitter) => emitter (document ["sequence"], 1), "1");

            var query = view.CreateQuery().ToLiveQuery();
            query.StartKey = 23;
            query.EndKey = 33;

            Log.I(Tag, "Created  " + query);

            // these are the keys that we expect to see in the livequery change listener callback
            var expectedKeys = new HashSet<Int64>();
            for (var i = 23; i < 34; i++)
            {
                expectedKeys.AddItem(i);
            }

            // install a change listener which decrements countdown latch when it sees a new
            // key from the list of expected keys
            EventHandler<QueryChangeEventArgs> handler = (sender, e) => {
                var rows = e.Rows;
                foreach(var row in rows)
                {
                    if (expectedKeys.Contains((Int64)row.Key))
                    {
                        Log.I(Tag, " doneSignal decremented " + doneSignal.CurrentCount);
                        doneSignal.Signal();
                    }
                }
            };

            query.Changed += handler;

            // create the docs that will cause the above change listener to decrement countdown latch
            var createTask = CreateDocumentsAsync(db, n: 50);
            createTask.Wait(TimeSpan.FromSeconds(5));
            if (methodNameToCall.Equals("start"))
            {
                // start the livequery running asynchronously
                query.Start();
            }
            else if (methodNameToCall.Equals("startWaitForRows")) 
            {
                query.Start();
                query.WaitForRows();
            }
            else
            {
                Assert.IsNull(query.Rows);

                query.Run();

                // this will block until the query completes
                Assert.IsNotNull(query.Rows);
            }

            // wait for the doneSignal to be finished
            var success = doneSignal.Wait(TimeSpan.FromSeconds(5));
            Assert.IsTrue(success, "Done signal timed out live query never ran");

            // stop the livequery since we are done with it
            query.Changed -= handler;
            query.Stop();
            query.Dispose();

            db.Close();
            createTask.Dispose();
            doneSignal.Dispose();
        }
        private static void QuickMonitor()
        {
            gateway = new Gateway();
            gateway.Configuration.GatewayName = "TESTGW";
            gateway.Configuration.LocalAddressSideA = "127.0.0.1:5432";
            //gateway.Configuration.LocalAddressSideA = "129.129.130.87:5555";
            gateway.Configuration.RemoteAddressSideA = "127.0.0.1:5552";
            gateway.Configuration.LocalAddressSideB = "129.129.130.87:5064";
            //gateway.Configuration.LocalAddressSideB = "172.22.200.116:5432";
            //gateway.Configuration.RemoteAddressSideB = remoteIp + ":5777";
            //gateway.Configuration.RemoteAddressSideB = "172.22.255.255:5064";
            gateway.Configuration.RemoteAddressSideB = "172.22.200.117:5062";
            gateway.Configuration.ConfigurationType = PBCaGw.Configurations.ConfigurationType.UNIDIRECTIONAL;
            gateway.SaveConfig();
            gateway.Start();

            Thread.Sleep(1000);

            EpicsClient client = new EpicsClient();
            string clientConfig = "127.0.0.1:5432";
            //string clientConfig="172.22.100.101:5064";
            client.Configuration.SearchAddress = clientConfig;

            //string[] channelNames = { "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL", "ZPSAF101-VME:CALNCONN.EGU", "ZPSAF101-VME:CALDCONN.EGU", "ZPSAF101-VME:LOAD", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:HBT" };
            //string[] channelNames = { "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CALNCONN.EGU", "ZPSAF101-VME:CALDCONN.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU" };
            string[] channelNames = { "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CALNCONN.EGU", "ZPSAF101-VME:CALDCONN.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:CAL.EGU", "ZPSAF101-VME:HBT.EGU", "ZPSAF101-VME:HBT.EGU", "ZPSAF101-VME:LOAD.EGU" };
            //string[] channelNames = { "ZPSAF101-VME:CAL.EGU" };
            while (true)
            {
                for (int l = 0; l < 10; l++)
                {
                    List<EpicsChannel<ExtGraphic<string>>> channels = new List<EpicsChannel<ExtGraphic<string>>>();
                    foreach (var i in channelNames)
                    {
                        EpicsChannel<ExtGraphic<string>> c = client.CreateChannel<ExtGraphic<string>>(i);
                        c.MonitorChanged += new EpicsDelegate<ExtGraphic<string>>(QuickMonitor);
                        channels.Add(c);
                    }
                    foreach (var i in channels)
                        i.Dispose();
                    client.Dispose();
                    client = new EpicsClient();
                    client.Configuration.SearchAddress = clientConfig;
                }

                if (true)
                {
                    bool gotError = false;
                    List<EpicsChannel<ExtGraphic<string>>> channels = new List<EpicsChannel<ExtGraphic<string>>>();
                    foreach (var i in channelNames)
                    {
                        EpicsChannel<ExtGraphic<string>> c = client.CreateChannel<ExtGraphic<string>>(i);
                        channels.Add(c);
                    }

                    CountdownEvent multiActionCountDown = new CountdownEvent(channelNames.Count());
                    Dictionary<uint, bool> gotMonitor = new Dictionary<uint, bool>();

                    foreach (EpicsChannel<ExtGraphic<string>> c in channels)
                    {
                        c.MonitorChanged += delegate(EpicsChannel<ExtGraphic<string>> sender, ExtGraphic<string> newValue)
                        {
                            if ((newValue.Value != "#" && sender.ChannelName.Contains(":CAL")) ||
                                (newValue.Value != "%" && sender.ChannelName.Contains(":LOAD")) ||
                                (newValue.Value != "ticks" && sender.ChannelName.Contains(":HBT")))
                            {
                                Console.WriteLine("Wrong data on CID (" + sender.ChannelName + "): " + sender.CID + ", " + newValue.Value);
                                gotError = true;
                            }
                            lock (gotMonitor)
                            {
                                if (!gotMonitor.ContainsKey(sender.CID))
                                {
                                    gotMonitor.Add(sender.CID, true);
                                    multiActionCountDown.Signal();
                                }
                            }
                        };

                        c.MonitorChanged += new EpicsDelegate<ExtGraphic<string>>(QuickMonitor);
                    }

                    multiActionCountDown.Wait(2500);

                    bool allConnected = true;
                    foreach (var i in channels)
                    {
                        if (i.Status != ChannelStatus.CONNECTED)
                        {
                            allConnected = false;
                            Console.WriteLine(i.ChannelName + " not connected.");
                            //gotError = true;
                        }
                    }

                    if (!allConnected)
                    {
                        needToShow = false;
                        //gotError = true;
                        Console.WriteLine("Not all connected!!!!!");
                    }

                    foreach (var i in channels)
                        i.Dispose();
                    client.Dispose();
                    client = new EpicsClient();
                    client.Configuration.SearchAddress = clientConfig;
                    multiActionCountDown.Dispose();

                    if (gotError)
                    {
                        Console.Beep();
                        Console.WriteLine("Press any key to continue...");
                        Console.ReadKey();
                        needToShow = true;
                    }
                }
            }
        }
		public void Dispose_Double ()
		{
			var ce = new CountdownEvent (1);
			ce.Dispose ();
			ce.Dispose ();
		}
		public void Dispose ()
		{
			var ce = new CountdownEvent (1);
			ce.Dispose ();
			Assert.AreEqual (1, ce.CurrentCount, "#0a");
			Assert.AreEqual (1, ce.InitialCount, "#0b");
			Assert.IsFalse (ce.IsSet, "#0c");

			try {
				ce.AddCount ();
				Assert.Fail ("#1");
			} catch (ObjectDisposedException) {
			}

			try {
				ce.Reset ();
				Assert.Fail ("#2");
			} catch (ObjectDisposedException) {
			}

			try {
				ce.Signal ();
				Assert.Fail ("#3");
			} catch (ObjectDisposedException) {
			}

			try {
				ce.TryAddCount ();
				Assert.Fail ("#4");
			} catch (ObjectDisposedException) {
			}

			try {
				ce.Wait (5);
				Assert.Fail ("#4");
			} catch (ObjectDisposedException) {
			}

			try {
				var v = ce.WaitHandle;
				Assert.Fail ("#5");
			} catch (ObjectDisposedException) {
			}
		}
		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 ();
			});
		}
        /// <summary>
        /// Receives the messages in an asynchronous loop and closes the session once there are no more messages.
        /// </summary>
        private void ReceiveMessagesAndCloseSession(MessageSession session, CancellationToken cancellationToken)
        {
            CountdownEvent unreleasedMessages = new CountdownEvent(1);

            Action<bool> closeSession = (bool success) =>
            {
                Action doClose = () =>
                    {
                        try
                        {
                            unreleasedMessages.Signal();
                            if (!unreleasedMessages.Wait(15000, cancellationToken))
                            {
                                Trace.TraceWarning("Waited for pending unreleased messages before closing session in subscription {0} but they did not complete in time", this.subscription);
                            }
                        }
                        catch (OperationCanceledException)
                        {
                        }
                        finally
                        {
                            unreleasedMessages.Dispose();
                        }

                        this.receiveRetryPolicy.ExecuteAction(
                            cb => session.BeginClose(cb, null),
                            session.EndClose,
                            () =>
                            {
                                this.instrumentation.SessionEnded();
                                if (success)
                                {
                                    this.dynamicThrottling.NotifyWorkCompleted();
                                }
                                else
                                {
                                    this.dynamicThrottling.NotifyWorkCompletedWithError();
                                }
                            },
                            ex =>
                            {
                                this.instrumentation.SessionEnded();
                                Trace.TraceError("An unrecoverable error occurred while trying to close a session in subscription {1}:\r\n{0}", ex, this.subscription);
                                this.dynamicThrottling.NotifyWorkCompletedWithError();
                            });
                    };

                if (this.requiresSequentialProcessing)
                {
                    doClose.Invoke();
                }
                else
                {
                    // Allow some time for releasing the messages before closing. Also, continue in a non I/O completion thread in order to block.
                    TaskEx.Delay(200).ContinueWith(t => doClose());
                }
            };

            // Declare an action to receive the next message in the queue or closes the session if cancelled.
            Action receiveNext = null;

            // Declare an action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
            Action<Exception> recoverReceive = null;

            // Declare an action responsible for the core operations in the message receive loop.
            Action receiveMessage = (() =>
            {
                // Use a retry policy to execute the Receive action in an asynchronous and reliable fashion.
                this.receiveRetryPolicy.ExecuteAction
                (
                    cb =>
                    {
                        // Start receiving a new message asynchronously.
                        // Does not wait for new messages to arrive in a session. If no further messages we will just close the session.
                        session.BeginReceive(TimeSpan.Zero, cb, null);
                    },
                    // Complete the asynchronous operation. This may throw an exception that will be handled internally by retry policy.
                    session.EndReceive,
                    msg =>
                    {
                        // Process the message once it was successfully received
                        // Check if we actually received any messages.
                        if (msg != null)
                        {
                            var roundtripStopwatch = Stopwatch.StartNew();
                            long schedulingElapsedMilliseconds = 0;
                            long processingElapsedMilliseconds = 0;

                            unreleasedMessages.AddCount();

                            Task.Factory.StartNew(() =>
                                {
                                    var releaseAction = MessageReleaseAction.AbandonMessage;

                                    try
                                    {
                                        this.instrumentation.MessageReceived();

                                        schedulingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds;

                                        // Make sure the process was told to stop receiving while it was waiting for a new message.
                                        if (!cancellationToken.IsCancellationRequested)
                                        {
                                            try
                                            {
                                                try
                                                {
                                                    // Process the received message.
                                                    releaseAction = this.InvokeMessageHandler(msg);

                                                    processingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds - schedulingElapsedMilliseconds;
                                                    this.instrumentation.MessageProcessed(releaseAction.Kind == MessageReleaseActionKind.Complete, processingElapsedMilliseconds);
                                                }
                                                catch
                                                {
                                                    processingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds - schedulingElapsedMilliseconds;
                                                    this.instrumentation.MessageProcessed(false, processingElapsedMilliseconds);

                                                    throw;
                                                }
                                            }
                                            finally
                                            {
                                                if (roundtripStopwatch.Elapsed > TimeSpan.FromSeconds(45))
                                                {
                                                    this.dynamicThrottling.Penalize();
                                                }
                                            }
                                        }
                                    }
                                    finally
                                    {
                                        // Ensure that any resources allocated by a BrokeredMessage instance are released.
                                        if (this.requiresSequentialProcessing)
                                        {
                                            this.ReleaseMessage(msg, releaseAction, () => { receiveNext(); }, () => { closeSession(false); }, unreleasedMessages, processingElapsedMilliseconds, schedulingElapsedMilliseconds, roundtripStopwatch);
                                        }
                                        else
                                        {
                                            // Receives next without waiting for the message to be released.
                                            this.ReleaseMessage(msg, releaseAction, () => { }, () => { this.dynamicThrottling.Penalize(); }, unreleasedMessages, processingElapsedMilliseconds, schedulingElapsedMilliseconds, roundtripStopwatch);
                                            receiveNext.Invoke();
                                        }
                                    }
                                });
                        }
                        else
                        {
                            // no more messages in the session, close it and do not continue receiving
                            closeSession(true);
                        }
                    },
                    ex =>
                    {
                        // Invoke a custom action to indicate that we have encountered an exception and
                        // need further decision as to whether to continue receiving messages.
                        recoverReceive.Invoke(ex);
                    });
            });

            // Initialize an action to receive the next message in the queue or closes the session if cancelled.
            receiveNext = () =>
            {
                if (!cancellationToken.IsCancellationRequested)
                {
                    // Continue receiving and processing new messages until told to stop.
                    receiveMessage.Invoke();
                }
                else
                {
                    closeSession(true);
                }
            };

            // Initialize a custom action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
            recoverReceive = ex =>
            {
                // Just log an exception. Do not allow an unhandled exception to terminate the message receive loop abnormally.
                Trace.TraceError("An unrecoverable error occurred while trying to receive a new message from subscription {1}:\r\n{0}", ex, this.subscription);

                // Cannot continue to receive messages from this session.
                closeSession(false);
            };

            // Start receiving messages asynchronously for the session.
            receiveNext.Invoke();
        }
Example #13
0
        public void ManualResetEventSlim_SetAfterDisposeTest()
        {
            ManualResetEventSlim mre = new ManualResetEventSlim();

            ParallelTestHelper.Repeat(delegate
            {
                Exception disp = null, setting = null;

                CountdownEvent evt = new CountdownEvent(2);
                CountdownEvent evtFinish = new CountdownEvent(2);

                Task.Factory.StartNew(delegate
                {
                    try
                    {
                        evt.Signal();
                        evt.Wait(1000);
                        mre.Dispose();
                    }
                    catch (Exception e)
                    {
                        disp = e;
                    }
                    evtFinish.Signal();
                });
                Task.Factory.StartNew(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();
            });
        }
Example #14
0
        public static void RunCountdownEventTest2_Exceptions()
        {
            CountdownEvent cde = null;
            Assert.Throws<ArgumentOutOfRangeException>(() => cde = new CountdownEvent(-1));
            // Failure Case: Constructor didn't throw AORE when -1 passed

            cde = new CountdownEvent(1);
            Assert.Throws<ArgumentOutOfRangeException>(() => cde.Signal(0));
            // Failure Case: Signal didn't throw AORE when 0 passed

            cde = new CountdownEvent(0);
            Assert.Throws<InvalidOperationException>(() => cde.Signal());
            // Failure Case: Signal didn't throw IOE when the count is zero

            cde = new CountdownEvent(1);
            Assert.Throws<InvalidOperationException>(() => cde.Signal(2));
            // Failure Case: Signal didn't throw IOE when the signal count > current count

            Assert.Throws<ArgumentOutOfRangeException>(() => cde.AddCount(0));
            // Failure Case: AddCount didn't throw AORE when 0 passed

            cde = new CountdownEvent(0);
            Assert.Throws<InvalidOperationException>(() => cde.AddCount(1));
            // Failure Case: AddCount didn't throw IOE when the count is zero

            cde = new CountdownEvent(int.MaxValue - 10);
            Assert.Throws<InvalidOperationException>(() => cde.AddCount(20));
            // Failure Case: AddCount didn't throw IOE when the count > int.Max

            cde = new CountdownEvent(2);
            Assert.Throws<ArgumentOutOfRangeException>(() => cde.Reset(-1));
            // Failure Case: Reset didn't throw AORE when the count is zero

            Assert.Throws<ArgumentOutOfRangeException>(() => cde.Wait(-2));
            // Failure Case: Wait(int) didn't throw AORE when the totalmilliseconds < -1

            Assert.Throws<ArgumentOutOfRangeException>(() => cde.Wait(TimeSpan.FromDays(-1)));
            // Failure Case:  FAILED.  Wait(TimeSpan) didn't throw AORE when the totalmilliseconds < -1

            Assert.Throws<ArgumentOutOfRangeException>(() => cde.Wait(TimeSpan.MaxValue));
            // Failure Case: Wait(TimeSpan, CancellationToken) didn't throw AORE when the totalmilliseconds > int.max

            Assert.Throws<ArgumentOutOfRangeException>(() => cde.Wait(TimeSpan.FromDays(-1), new CancellationToken()));
            // Failure Case: Wait(TimeSpan) didn't throw AORE when the totalmilliseconds < -1

            Assert.Throws<ArgumentOutOfRangeException>(() => cde.Wait(TimeSpan.MaxValue, new CancellationToken()));
            // Failure Case: Wait(TimeSpan, CancellationToken) didn't throw AORE when the totalmilliseconds > int.max

            cde.Dispose();

            Assert.Throws<ObjectDisposedException>(() => cde.Wait());
            // Failure Case: Wait() didn't throw ODE after Dispose
        }
Example #15
0
        public Statistic RunExperiment(CalculationParameters param)
        {
            CheckParameters(param);

            var sw = Stopwatch.StartNew();

            SimulatedGamesCount = 0;

            Card player_card1 = param.PlayerCard1;
            Card player_card2 = param.PlayerCard2;

            Card[] open_cards = GetOpenCards(param);
            ValidateInputCards(player_card1, player_card2, open_cards);

            Card[] cards = GetAllCards();

            Card[] free_cards = GetFreeCards(cards, player_card1, player_card2, open_cards);

            var stat = new StatisticInternal();
            stat.Init();

            int parallelLevel = param.ParallelLevel;

            #if OneThreadForDBG
            parallelLevel = 1;
            #endif

            int enemyPlayersCount = param.EnemyPlayersCount;
            int gameNumber = param.GameNumber;

            var semaphore = new SemaphoreSlim(parallelLevel);
            var countdown = new CountdownEvent(gameNumber);

            for (int i = 0; i < gameNumber; i++)
            {
                param.CancelToken.ThrowIfCancellationRequested();

                if (param.TimeLimit.HasValue
                    && sw.Elapsed > param.TimeLimit.Value)
                {
                    countdown.Signal(gameNumber - i);
                    break;
                }

                semaphore.Wait();
                SimulatedGamesCount++;

                Action action =
                    () =>
                    {
                        try
                        {
                            SimulateGame(player_card1, player_card2, open_cards, free_cards, enemyPlayersCount, stat, param);
                        }
                        finally
                        {
                            semaphore.Release();
                            countdown.Signal();
                        }
                    };

                if (parallelLevel == 1)
                {
                    action();
                }
                else
                {
                    Task.Factory.StartNew(action);
                }
            }

            countdown.Wait();
            countdown.Dispose();
            semaphore.Dispose();

            Statistic public_stat = PreparePublicStatistic(stat);

            return public_stat;
        }
        static async Task Main(string[] args)
        {
            // Initialize a queue and a CountdownEvent
            ConcurrentQueue <int> queue = new ConcurrentQueue <int>(Enumerable.Range(0, 10000));

            System.Threading.CountdownEvent cde = new System.Threading.CountdownEvent(10000);             // initial count = 10000

            // This is the logic for all queue consumers
            Action consumer = () =>
            {
                int local;
                // decrement CDE count once for each element consumed from queue
                while (queue.TryDequeue(out local))
                {
                    cde.Signal();
                }
            };

            // Now empty the queue with a couple of asynchronous tasks
            Task t1 = Task.Factory.StartNew(consumer);
            Task t2 = Task.Factory.StartNew(consumer);

            // And wait for queue to empty by waiting on cde
            cde.Wait();             // will return when cde count reaches 0

            Console.WriteLine("Done emptying queue.  InitialCount={0}, CurrentCount={1}, IsSet={2}",
                              cde.InitialCount, cde.CurrentCount, cde.IsSet);

            // Proper form is to wait for the tasks to complete, even if you that their work
            // is done already.
            await Task.WhenAll(t1, t2);

            // Resetting will cause the CountdownEvent to un-set, and resets InitialCount/CurrentCount
            // to the specified value
            cde.Reset(10);

            // AddCount will affect the CurrentCount, but not the InitialCount
            cde.AddCount(2);

            Console.WriteLine("After Reset(10), AddCount(2): InitialCount={0}, CurrentCount={1}, IsSet={2}",
                              cde.InitialCount, cde.CurrentCount, cde.IsSet);

            // Now try waiting with cancellation
            CancellationTokenSource cts = new CancellationTokenSource();

            cts.Cancel();             // cancels the CancellationTokenSource
            try
            {
                cde.Wait(cts.Token);
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("cde.Wait(preCanceledToken) threw OCE, as expected");
            }
            finally
            {
                cts.Dispose();
            }
            // It's good to release a CountdownEvent when you're done with it.
            cde.Dispose();

            Console.ReadLine();
        }