public async Task HandleableCollectionThrowsWhenDisposedTest() { var collection = new HandleableCollection <int>(); AddRangeAndVerifyItems(collection, endInclusive: 9); HandleableCollection <int> .Handler handler = (int item, out bool removeItem) => { removeItem = false; return(20 == item); }; using var cancellation = new CancellationTokenSource(DefaultPositiveVerificationTimeout); Task handleTask = Task.Run(() => collection.Handle(handler, DefaultPositiveVerificationTimeout)); Task handleAsyncTask = collection.HandleAsync(handler, cancellation.Token); // Task.Delay intentionally shorter than default timeout to check that Handle* // calls did not complete quickly. Task delayTask = Task.Delay(TimeSpan.FromSeconds(1)); Task completedTask = await Task.WhenAny(delayTask, handleTask, handleAsyncTask); // Check that the handle tasks didn't complete Assert.Equal(delayTask, completedTask); collection.Dispose(); // Incomplete calls from prior to disposal should throw ObjectDisposedException await Assert.ThrowsAsync <ObjectDisposedException>(() => handleTask); await Assert.ThrowsAsync <ObjectDisposedException>(() => handleAsyncTask); // New calls should throw ObjectDisposedException Assert.Throws <ObjectDisposedException>( () => collection.Add(10)); Assert.Throws <ObjectDisposedException>( () => collection.ClearItems()); Assert.Throws <ObjectDisposedException>( () => collection.Handle(DefaultPositiveVerificationTimeout)); Assert.Throws <ObjectDisposedException>( () => collection.Handle(handler, DefaultPositiveVerificationTimeout)); await Assert.ThrowsAsync <ObjectDisposedException>( () => collection.HandleAsync(cancellation.Token)); await Assert.ThrowsAsync <ObjectDisposedException>( () => collection.HandleAsync(handler, cancellation.Token)); Assert.Throws <ObjectDisposedException>( () => ((IEnumerable)collection).GetEnumerator()); Assert.Throws <ObjectDisposedException>( () => ((IEnumerable <int>)collection).GetEnumerator()); }
public async Task HandleableCollectionClearItemsTest() { using var collection = new HandleableCollection <int>(); Assert.Empty(collection); AddRangeAndVerifyItems(collection, endInclusive: 4); HandleableCollection <int> .Handler handler = (int value, out bool removeItem) => { if (value == 7) { removeItem = true; return(true); } removeItem = false; return(false); }; using var cancellation = new CancellationTokenSource(DefaultPositiveVerificationTimeout); Task handleAsyncTask = Task.Run(() => collection.HandleAsync(handler, cancellation.Token)); // Task.Delay intentionally shorter than default timeout to check that HandleAsync // calls did not complete quickly. Task delayTask = Task.Delay(TimeSpan.FromSeconds(1)); Task completedTask = await Task.WhenAny(delayTask, handleAsyncTask); // Check that the handle task didn't complete Assert.Equal(delayTask, completedTask); collection.ClearItems(); Assert.Empty(collection); // The remainder of the test checks that the previously registered handler is still // registered with the collection and was not removed by calling ClearItems. IList <(int, int)> itemsAndCounts = new List <(int, int)>(); itemsAndCounts.Add((6, 1)); itemsAndCounts.Add((7, 1)); // Item is consumed immediately, thus collection count does not change itemsAndCounts.Add((8, 2)); AddAndVerifyItems(collection, itemsAndCounts); // Task.Delay intentionally longer than default timeout to check that HandleAsync // does complete by handling a value. The delay Task is used in case the handler doesn't // handle a value and doesn't respect cancellation so as to not stall the test indefinitely. delayTask = Task.Delay(2 * DefaultPositiveVerificationTimeout); completedTask = await Task.WhenAny(delayTask, handleAsyncTask); // Check that the handle task did complete Assert.Equal(handleAsyncTask, completedTask); // Check that the value was removed Assert.Equal(new int[] { 6, 8 }, collection); }