diff --git a/src/Numerics/Threading/Parallel.cs b/src/Numerics/Threading/Parallel.cs
index dbab88c8..83315988 100644
--- a/src/Numerics/Threading/Parallel.cs
+++ b/src/Numerics/Threading/Parallel.cs
@@ -67,7 +67,9 @@ namespace MathNet.Numerics.Threading
// fast forward execution in case parallelization is disabled
// (cdrnet, 200908): should we fast forward on STA threads as well?
- if (Control.DisableParallelization || ThreadQueue.ThreadCount <= 1)
+ if (Control.DisableParallelization
+ || ThreadQueue.ThreadCount <= 1
+ || ThreadQueue.IsInWorkerThread)
{
for (int i = fromInclusive; i < toExclusive; i++)
{
@@ -136,7 +138,9 @@ namespace MathNet.Numerics.Threading
// fast forward execution in case parallelization is disabled
// (cdrnet, 200908): should we fast forward on STA threads as well?
- if (Control.DisableParallelization || ThreadQueue.ThreadCount <= 1)
+ if (Control.DisableParallelization
+ || ThreadQueue.ThreadCount <= 1
+ || ThreadQueue.IsInWorkerThread)
{
for (int i = 0; i < actions.Length; i++)
{
diff --git a/src/Numerics/Threading/ThreadQueue.cs b/src/Numerics/Threading/ThreadQueue.cs
index cfcdd780..555b41c9 100644
--- a/src/Numerics/Threading/ThreadQueue.cs
+++ b/src/Numerics/Threading/ThreadQueue.cs
@@ -77,6 +77,12 @@ namespace MathNet.Numerics.Threading
///
internal static int ThreadCount { get; private set; }
+ ///
+ /// Indicating whether the current thread is a parallelized worker thread.
+ ///
+ [ThreadStatic]
+ private static bool _isInWorkerThread;
+
///
/// Initializes static members of the ThreadQueue class.
///
@@ -85,6 +91,14 @@ namespace MathNet.Numerics.Threading
Start(Environment.ProcessorCount);
}
+ ///
+ /// Gets a value indicating whether the current thread is a parallelized worker thread.
+ ///
+ internal static bool IsInWorkerThread
+ {
+ get { return _isInWorkerThread; }
+ }
+
///
/// Add a job to the queue.
///
@@ -131,6 +145,8 @@ namespace MathNet.Numerics.Threading
///
private static void WorkerThreadStart()
{
+ _isInWorkerThread = true;
+
while (_running)
{
// Wait until a job is available, or we should shut down
diff --git a/src/UnitTests/ThreadingTests/ParallelTest.cs b/src/UnitTests/ThreadingTests/ParallelTest.cs
index 2e114dff..cc05e732 100644
--- a/src/UnitTests/ThreadingTests/ParallelTest.cs
+++ b/src/UnitTests/ThreadingTests/ParallelTest.cs
@@ -143,5 +143,48 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
Assert.AreEqual(1001, items[i], i.ToString());
}
}
+
+ [Test, ApartmentState(ApartmentState.MTA)]
+ public void DoesDetectAndResolveRecursiveParallelization()
+ {
+ int countSharedBetweenClosures = 0;
+
+ Assert.DoesNotThrow(
+ () =>
+ Parallel.For(
+ 0,
+ 10,
+ j => Interlocked.Increment(ref countSharedBetweenClosures)));
+
+ Assert.AreEqual(10, countSharedBetweenClosures);
+ countSharedBetweenClosures = 0;
+
+ Parallel.For(
+ 0,
+ 10,
+ i =>
+ Parallel.For(
+ 0,
+ 10,
+ j => Interlocked.Increment(ref countSharedBetweenClosures)));
+
+ Assert.AreEqual(100, countSharedBetweenClosures);
+ countSharedBetweenClosures = 0;
+
+ Parallel.For(
+ 0,
+ 10,
+ i =>
+ Parallel.For(
+ 0,
+ 10,
+ j =>
+ Parallel.For(
+ 0,
+ 10,
+ k => Interlocked.Increment(ref countSharedBetweenClosures))));
+
+ Assert.AreEqual(1000, countSharedBetweenClosures);
+ }
}
}
\ No newline at end of file