nsubstitute/NSubstitute — Issue #62: Multi-threaded calls to a substitute
Author: dtchepak
Created: 2011-10-14 12:50:42+00:00
State: open

Calling substitutes from multiple threads (e.g. using plinq / TPL) can cause problems.

Original report used parallel exec in the business logic and resulted in "Index outside of range exceptions" in System.Collections.Generic.Stack`1.Push(T item) inside the NSubstitute code. Exception frequency was 1 to 5 times out of 500 tests. Making `CallStack.cs` thread-safe seemed to fix this problem.

Report mentioned similar probs with Moq: http://code.google.com/p/moq/issues/detail?id=249 and http://code.google.com/p/moq/issues/detail?id=265

Example code:
````csharp
Queue fetchTaskQueue = new Queue();
fetchTaskQueue.Enqueue(Task.Factory.StartNew(() => task1 = this.dataAccess.GetMethod1(Id)));
fetchTaskQueue.Enqueue(Task.Factory.StartNew(() => task2 = this.dataAccess.GetMethod2(Id)));
fetchTaskQueue.Enqueue(Task.Factory.StartNew(() => task3 = this.dataAccess.GetMethod3(Id)));
fetchTaskQueue.Enqueue(Task.Factory.StartNew(() => task4 = this.dataAccess.GetMethod4(Id)));
fetchTaskQueue.Enqueue(Task.Factory.StartNew(() => task5 = this.dataAccess.GetMethod5(Id)));
fetchTaskQueue.Enqueue(Task.Factory.StartNew(() => task6 = this.dataAccess.GetMethod6(Id)));
fetchTaskQueue.Enqueue(Task.Factory.StartNew(() => task7 = this.dataAccess.GetMethod7(Id)));
Task.WaitAll(fetchTaskQueue.ToArray());
````

Thanks to Aleksander Spro for the report.