[Category("RaceToDeadLock")] // This test creates a race condition, that when resolved sequentially will be stuck public void Progressor_ThreadedUse() { var source = Progressor <int> .CreateFromIList ( new List <int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } ); var manualResetEvents = new ManualResetEvent[1]; using (manualResetEvents[0] = new ManualResetEvent(false)) { int[] count = { 0, 0, 0 }; void Work() { Interlocked.Increment(ref count[0]); manualResetEvents[0].WaitOne(); foreach (var item in source) { GC.KeepAlive(item); Interlocked.Increment(ref count[2]); } Interlocked.Increment(ref count[1]); } Task.Factory.StartNew(Work); Task.Factory.StartNew(Work); while (Volatile.Read(ref count[0]) != 2) { Thread.Sleep(0); } manualResetEvents[0].Set(); while (Volatile.Read(ref count[1]) != 2) { Thread.Sleep(0); } Assert.AreEqual(10, Volatile.Read(ref count[2])); #if TARGETS_NET || GREATERTHAN_NETCOREAPP11 || GREATERTHAN_NETSTANDARD16 manualResetEvents[0].Close(); #endif } }
public void ThreadedUse() { var source = Progressor <int> .CreateFromIList ( new List <int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } ); var manualResetEvents = new ManualResetEvent[1]; using (manualResetEvents[0] = new ManualResetEvent(false)) { int[] count = { 0, 0, 0 }; var work = new WaitCallback ( _ => { Interlocked.Increment(ref count[0]); manualResetEvents[0].WaitOne(); foreach (var item in source) { GC.KeepAlive(item); Interlocked.Increment(ref count[2]); } Interlocked.Increment(ref count[1]); } ); ThreadPool.QueueUserWorkItem(work); ThreadPool.QueueUserWorkItem(work); while (Volatile.Read(ref count[0]) != 2) { Thread.Sleep(1); } manualResetEvents[0].Set(); while (Volatile.Read(ref count[1]) != 2) { Thread.Sleep(1); } Assert.AreEqual(10, Volatile.Read(ref count[2])); } }
public override IEnumerable <T> GetDynamicPartitions() { if (_source is T[] array) { return(Progressor <T> .CreateFromArray(array)); } if (_source is IList <T> list) { return(Progressor <T> .CreateFromIList(list)); } return(Progressor <T> .CreateFromIEnumerable(_source)); }
[Category("RaceToDeadLock")] // This test creates a race condition, that when resolved sequentially will be stuck public void Progressor_ThreadedUse() // TODO: Review { var source = Progressor <int> .CreateFromIList(new List <int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); using (var handle = new ManualResetEvent(false)) { int[] count = { 0, 0, 0 }; void Work() { Interlocked.Increment(ref count[0]); handle.WaitOne(); foreach (var item in source) { GC.KeepAlive(item); Interlocked.Increment(ref count[2]); } Interlocked.Increment(ref count[1]); } Task.Factory.StartNew(Work); Task.Factory.StartNew(Work); while (Volatile.Read(ref count[0]) != 2) { Thread.Sleep(0); } handle.Set(); while (Volatile.Read(ref count[1]) != 2) { Thread.Sleep(0); } Assert.AreEqual(10, Volatile.Read(ref count[2])); handle.Close(); } }