https://issues.apache.org/jira/browse/AMQNET-488

Apply fix for potential deadlock on transport dispose during failover.
diff --git a/src/main/csharp/Threads/CompositeTaskRunner.cs b/src/main/csharp/Threads/CompositeTaskRunner.cs
index d081d35..96305c6 100755
--- a/src/main/csharp/Threads/CompositeTaskRunner.cs
+++ b/src/main/csharp/Threads/CompositeTaskRunner.cs
@@ -17,6 +17,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading;
 
 namespace Apache.NMS.ActiveMQ.Threads
@@ -185,21 +186,28 @@
 		
 		private bool Iterate()
 		{
-			lock(mutex)
-			{
-				foreach(CompositeTask task in this.tasks)
-				{
-					if(task.IsPending)
-					{
-						task.Iterate();
+		    Task pendingTask = null;
 
-						// Always return true here so that we can check the next
-						// task in the list to see if its done.
-						return true;
-					}
-				}
+            lock (mutex)
+		    {                
+                foreach (CompositeTask task in this.tasks)
+			    {            
+                    if (task.IsPending)
+                    {
+                        pendingTask = task;
+                        break;
+                    }
+                }
+            }
+
+            if (pendingTask != null)
+			{
+                pendingTask.Iterate();
+				// Always return true here so that we can check the next
+			    // task in the list to see if its done.
+				return true;
 			}
-			
+
 			return false;
 		}
     }
diff --git a/src/test/csharp/Threads/CompositeTaskRunnerTest.cs b/src/test/csharp/Threads/CompositeTaskRunnerTest.cs
index 133ac43..1f42934 100644
--- a/src/test/csharp/Threads/CompositeTaskRunnerTest.cs
+++ b/src/test/csharp/Threads/CompositeTaskRunnerTest.cs
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+using System;
 using System.Threading;
 using Apache.NMS.ActiveMQ.Threads;
 using NUnit.Framework;
@@ -24,7 +25,6 @@
     [TestFixture]
     public class CompositeTaskRunnerTest
     {
-
         class CountingTask : CompositeTask
         {
             private int count;
@@ -90,5 +90,59 @@
             runner.RemoveTask(task1);
             runner.RemoveTask(task2);
         }
+
+        [Test]
+        public void CompositeTaskRunnerDoesntHoldLockWhileCallingIterate()
+        {
+            object lockObj = new object();
+            
+            // Start a task running that takes a shared lock during it's iterate.
+            CompositeTaskRunner runner = new CompositeTaskRunner();
+            runner.AddTask(new LockingTask(lockObj));
+           
+            // Start a separate thread that holds that same lock whilst manipulating the CompositeTaskRunner (See InactivityMonitor for real example).
+            AutoResetEvent resetEvent = new AutoResetEvent(false);
+
+            ThreadPool.QueueUserWorkItem(_ =>
+            {
+                for (int i = 0; i < 10000; i++)
+                {
+                    lock (lockObj)
+                    {
+                        var countingTask = new CountingTask("task1", 100);
+                        runner.AddTask(countingTask);
+                        runner.RemoveTask(countingTask);
+                    }
+                }
+
+                resetEvent.Set();
+            });
+
+            // Wait for the second thread to finish 10000 attempts.
+            Assert.That(resetEvent.WaitOne(TimeSpan.FromSeconds(10)), "The secondary lock user didn't finish 10000 iterations in less than 10 seconds. Probably dead locked!");
+            runner.Shutdown();
+        }
+
+        private class LockingTask : CompositeTask
+        {
+            private readonly object _lockObj;
+
+            public LockingTask(object lockObj)
+            {
+                _lockObj = lockObj;
+                IsPending = true;
+            }
+
+            public bool Iterate()
+            {
+                lock (_lockObj)
+                {
+                    Thread.Sleep(10);
+                }
+                return true;
+            }
+
+            public bool IsPending { get; private set; }
+        }
     }
-}
+}
\ No newline at end of file