public void Error() { AsyncManualResetEvent manualEvent; // Verify that we get and [ObjectDisposedException] for [Set()] and [Reset()] // a disposed event. manualEvent = new AsyncManualResetEvent(); manualEvent.Dispose(); Assert.Throws <ObjectDisposedException>(() => manualEvent.Set()); Assert.Throws <ObjectDisposedException>(() => manualEvent.Reset()); Task.Run(() => Assert.ThrowsAsync <ObjectDisposedException>(async() => await manualEvent.WaitAsync())).Wait(); // Verify that disposing an event causes any waiting tasks // to unblock with an [ObjectDisposedException]. manualEvent = new AsyncManualResetEvent(); var taskInfo = new TaskStateCollection(); var badException = false; for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; try { await manualEvent.WaitAsync(); } catch (ObjectDisposedException) { taskInfo[taskIndex].IsFaulted = true; } catch { badException = true; taskInfo[taskIndex].IsFaulted = true; } taskInfo[taskIndex].IsComplete = true; }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); Assert.False(taskInfo.AnyComplete); manualEvent.Dispose(); NeonHelper.WaitFor(() => taskInfo.AllFaulted, defaultTimeout); Assert.False(badException); }
public void MultipleThreads() { // Verify that an event that starts out unsignalled doesn't allow // any tasks to execute. using (var manualEvent = new AsyncManualResetEvent(false)) { var taskInfo = new TaskStateCollection(); for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; try { await manualEvent.WaitAsync(); taskInfo[taskIndex].IsComplete = true; } catch (ObjectDisposedException) { // Ignore these } }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.False(taskInfo.AnyComplete); } // Verify that an event that starts out signalled allows // multiple tasks to execute. using (var manualEvent = new AsyncManualResetEvent(true)) { var taskInfo = new TaskStateCollection(); for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; await manualEvent.WaitAsync(); taskInfo[taskIndex].IsComplete = true; }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); NeonHelper.WaitFor(() => taskInfo.AllComplete, defaultTimeout); } // Verify that an event that starts out unsignalled and is subsequently // signalled allows multiple tasks to complete. using (var manualEvent = new AsyncManualResetEvent(false)) { var taskInfo = new TaskStateCollection(); for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; await manualEvent.WaitAsync(); taskInfo[taskIndex].IsComplete = true; }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); Assert.False(taskInfo.AnyComplete); manualEvent.Set(); NeonHelper.WaitFor(() => taskInfo.AllComplete, defaultTimeout); } // Verify that we can reuse an event multiple times for multiple tasks. using (var manualEvent = new AsyncManualResetEvent(false)) { for (int j = 0; j < 10; j++) { var taskInfo = new TaskStateCollection(); for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; await manualEvent.WaitAsync(); taskInfo[taskIndex].IsComplete = true; }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); Assert.False(taskInfo.AnyComplete); manualEvent.Set(); NeonHelper.WaitFor(() => taskInfo.AllComplete, defaultTimeout); manualEvent.Reset(); } } }
public void Basic() { // Verify that an event that starts out unsignalled doesn't allow // any tasks to execute. using (var autoEvent = new AsyncAutoResetEvent(false)) { var taskInfo = new TaskStateCollection(); for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; try { await autoEvent.WaitAsync(); taskInfo[taskIndex].IsComplete = true; } catch (ObjectDisposedException) { // Ignore these } }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.False(taskInfo.AnyComplete); } // Verify that an event that starts out signalled but then // resetting it doesn't allow any tasks to execute. using (var autoEvent = new AsyncAutoResetEvent(true)) { autoEvent.Reset(); var taskInfo = new TaskStateCollection(); for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; try { await autoEvent.WaitAsync(); taskInfo[taskIndex].IsComplete = true; } catch (ObjectDisposedException) { // Ignore these } }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.False(taskInfo.AnyComplete); } // Verify that an event that starts out unsignalled doesn't allow // any tasks to execute and then that every time the event is signalled, // a single task is unblocked. using (var autoEvent = new AsyncAutoResetEvent(false)) { var taskInfo = new TaskStateCollection(); for (int i = 0; i < taskInfo.Count; i++) { new Task( async state => { int taskIndex = (int)state; taskInfo[taskIndex].IsRunning = true; try { await autoEvent.WaitAsync(); taskInfo[taskIndex].IsComplete = true; } catch (ObjectDisposedException) { // Ignore these } }, i).Start(); } NeonHelper.WaitFor(() => taskInfo.AllRunning, defaultTimeout); Thread.Sleep(TimeSpan.FromSeconds(5)); Assert.False(taskInfo.AnyComplete); for (int i = 0; i < taskInfo.Count; i++) { autoEvent.Set(); NeonHelper.WaitFor( () => { return(taskInfo.Where(ti => ti.IsComplete).Count() == i + 1); }, defaultTimeout); } // Also verify that disposing the event multiple time isn't a problem. autoEvent.Dispose(); } }