Take a look at your first test, Can_add_one_item_at_a_time .
First of all, your exit conditions do not make sense. Both elements must be added, one at a time. Therefore, of course, your test will fail.
You also do not need to take a picture; remember that this is a test, nothing else will touch the list during your test.
And last, but not least, you need to make sure that you are not trying to evaluate the exit conditions until all threads run out. The easiest way is to use a counter and a wait event. Here is an example:
[Test] public void Can_add_from_multiple_threads() { const int MaxWorkers = 10; var list = new ThreadSafeList<int>(MaxWorkers); int remainingWorkers = MaxWorkers; var workCompletedEvent = new ManualResetEvent(false); for (int i = 0; i < MaxWorkers; i++) { int workerNum = i;
Now this means that Add happening so fast that neither of the two threads will ever try to do this at the same time. No return No return partially explained how to insert a conditional delay. I would actually define a special test flag instead of DEBUG . In your build configuration, add a flag called TEST , then add this to your ThreadSafeList class:
public class ThreadSafeList<T> { // snip fields public void Add(T item) { lock (sync) { TestUtil.WaitStandardThreadDelay(); innerList.Add(item); } } // snip other methods/properties } static class TestUtil { [Conditional("TEST")] public static void WaitStandardThreadDelay() { Thread.Sleep(1000); } }
This will cause the Add method to wait 1 second before the item is actually added if the assembly configuration defines the TEST flag. The entire test should take at least 10 seconds; if it ends faster, something is wrong.
With that in mind, I will leave the second test to you. It looks like.
source share