diff --git a/src/main/csharp/Transport/InactivityMonitor.cs b/src/main/csharp/Transport/InactivityMonitor.cs
index fc7c1e0..a13041c 100644
--- a/src/main/csharp/Transport/InactivityMonitor.cs
+++ b/src/main/csharp/Transport/InactivityMonitor.cs
@@ -23,459 +23,467 @@
 
 namespace Apache.NMS.ActiveMQ.Transport
 {
-	/// <summary>
-	/// This class make sure that the connection is still alive,
-	/// by monitoring the reception of commands from the peer of
-	/// the transport.
-	/// </summary>
-	public class InactivityMonitor : TransportFilter
-	{
-		private readonly Atomic<bool> monitorStarted = new Atomic<bool>(false);
+    /// <summary>
+    /// This class make sure that the connection is still alive,
+    /// by monitoring the reception of commands from the peer of
+    /// the transport.
+    /// </summary>
+    public class InactivityMonitor : TransportFilter
+    {
+        private readonly Atomic<bool> monitorStarted = new Atomic<bool>(false);
 
-		private readonly Atomic<bool> commandSent = new Atomic<bool>(false);
-		private readonly Atomic<bool> commandReceived = new Atomic<bool>(false);
+        private readonly Atomic<bool> commandSent = new Atomic<bool>(false);
+        private readonly Atomic<bool> commandReceived = new Atomic<bool>(false);
 
-		private readonly Atomic<bool> failed = new Atomic<bool>(false);
-		private readonly Atomic<bool> inRead = new Atomic<bool>(false);
-		private readonly Atomic<bool> inWrite = new Atomic<bool>(false);
+        private readonly Atomic<bool> failed = new Atomic<bool>(false);
+        private readonly Atomic<bool> inRead = new Atomic<bool>(false);
+        private readonly Atomic<bool> inWrite = new Atomic<bool>(false);
 
-		private CompositeTaskRunner asyncTasks;
-		private AsyncSignalReadErrorkTask asyncErrorTask;
-		private AsyncWriteTask asyncWriteTask;
+        private CompositeTaskRunner asyncTasks;
+        private AsyncSignalReadErrorkTask asyncErrorTask;
+        private AsyncWriteTask asyncWriteTask;
 
-		private readonly Mutex monitor = new Mutex();
+        private readonly Mutex monitor = new Mutex();
 
-		private Timer connectionCheckTimer;
+        private Timer connectionCheckTimer;
 
-		private DateTime lastReadCheckTime;
+        private DateTime lastReadCheckTime;
 
-		private static int id = 0;
-		private readonly int instanceId = 0;
-		private bool disposing = false;
+        private static int id = 0;
+        private readonly int instanceId = 0;
+        private bool disposing = false;
 
-		private long readCheckTime;
-		public long ReadCheckTime
-		{
-			get { return this.readCheckTime; }
-			set { this.readCheckTime = value; }
-		}
+        private long readCheckTime;
+        public long ReadCheckTime
+        {
+            get { return this.readCheckTime; }
+            set { this.readCheckTime = value; }
+        }
 
-		private long writeCheckTime;
-		public long WriteCheckTime
-		{
-			get { return this.writeCheckTime; }
-			set { this.writeCheckTime = value; }
-		}
+        private long writeCheckTime;
+        public long WriteCheckTime
+        {
+            get { return this.writeCheckTime; }
+            set { this.writeCheckTime = value; }
+        }
 
-		private long initialDelayTime;
-		public long InitialDelayTime
-		{
-			get { return this.initialDelayTime; }
-			set { this.initialDelayTime = value; }
-		}
+        private long initialDelayTime;
+        public long InitialDelayTime
+        {
+            get { return this.initialDelayTime; }
+            set { this.initialDelayTime = value; }
+        }
 
-		private readonly Atomic<bool> keepAliveResponseRequired = new Atomic<bool>(false);
-		public bool KeepAliveResponseRequired
-		{
-			get { return this.keepAliveResponseRequired.Value; }
-			set { keepAliveResponseRequired.Value = value; }
-		}
+        private readonly Atomic<bool> keepAliveResponseRequired = new Atomic<bool>(false);
+        public bool KeepAliveResponseRequired
+        {
+            get { return this.keepAliveResponseRequired.Value; }
+            set { keepAliveResponseRequired.Value = value; }
+        }
 
-		// Local and remote Wire Format Information
-		private WireFormatInfo localWireFormatInfo;
-		private WireFormatInfo remoteWireFormatInfo;
+        // Local and remote Wire Format Information
+        private WireFormatInfo localWireFormatInfo;
+        private WireFormatInfo remoteWireFormatInfo;
 
-		/// <summary>
-		/// Constructor or the Inactivity Monitor
-		/// </summary>
-		/// <param name="next"></param>
-		public InactivityMonitor(ITransport next)
-			: base(next)
-		{
-			this.instanceId = ++id;
-			Tracer.Debug("Creating Inactivity Monitor: " + instanceId);
-		}
+        /// <summary>
+        /// Constructor or the Inactivity Monitor
+        /// </summary>
+        /// <param name="next"></param>
+        public InactivityMonitor(ITransport next)
+            : base(next)
+        {
+            this.instanceId = ++id;
+            Tracer.Debug("Creating Inactivity Monitor: " + instanceId);
+        }
 
-		~InactivityMonitor()
-		{
-			Dispose(false);
-		}
+        ~InactivityMonitor()
+        {
+            Dispose(false);
+        }
 
-		protected override void Dispose(bool disposing)
-		{
-			if(disposing)
-			{
-				// get rid of unmanaged stuff
-			}
+        protected override void Dispose(bool disposing)
+        {
+            if(disposing)
+            {
+                // get rid of unmanaged stuff
+            }
 
-			lock(monitor)
-			{
-				this.localWireFormatInfo = null;
-				this.remoteWireFormatInfo = null;
-				this.disposing = true;
-				StopMonitorThreads();
-			}
+            lock(monitor)
+            {
+                this.localWireFormatInfo = null;
+                this.remoteWireFormatInfo = null;
+                this.disposing = true;
+                StopMonitorThreads();
+            }
 
-			base.Dispose(disposing);
-		}
+            base.Dispose(disposing);
+        }
 
-		public void CheckConnection(object state)
-		{
-			// First see if we have written or can write.
-			WriteCheck();
+        public void CheckConnection(object state)
+        {
+            // First see if we have written or can write.
+            WriteCheck();
 
-			// Now check is we've read anything, if not then we send
-			// a new KeepAlive with response required.
-			ReadCheck();
-		}
+            // Now check is we've read anything, if not then we send
+            // a new KeepAlive with response required.
+            ReadCheck();
+        }
 
-		#region WriteCheck Related
-		/// <summary>
-		/// Check the write to the broker
-		/// </summary>
-		public void WriteCheck()
-		{
-			if(this.inWrite.Value || this.failed.Value)
-			{
-				Tracer.DebugFormat("InactivityMonitor[{0}]: is in write or already failed.", instanceId);
-				return;
-			}
+        #region WriteCheck Related
+        /// <summary>
+        /// Check the write to the broker
+        /// </summary>
+        public void WriteCheck()
+        {
+            if(this.inWrite.Value || this.failed.Value)
+            {
+                Tracer.DebugFormat("InactivityMonitor[{0}]: is in write or already failed.", instanceId);
+                return;
+            }
 
-			if(!commandSent.Value)
-			{
-				Tracer.DebugFormat("InactivityMonitor[{0}]: No Message sent since last write check. Sending a KeepAliveInfo.", instanceId);
-				if(null != this.asyncWriteTask)
-				{
-					this.asyncWriteTask.IsPending = true;
-				}
-				
-				this.asyncTasks.Wakeup();
-			}
-			else
-			{
-				Tracer.DebugFormat("InactivityMonitor[{0}]: Message sent since last write check. Resetting flag.", instanceId);
-			}
+            CompositeTaskRunner taskRunner = this.asyncTasks;
 
-			commandSent.Value = false;
-		}
-		#endregion
+            if(!commandSent.Value)
+            {
+                Tracer.DebugFormat("InactivityMonitor[{0}]: No Message sent since last write check. Sending a KeepAliveInfo.", instanceId);
+                if(null != this.asyncWriteTask)
+                {
+                    this.asyncWriteTask.IsPending = true;
+                }
 
-		#region ReadCheck Related
-		public void ReadCheck()
-		{
-			DateTime now = DateTime.Now;
-			TimeSpan elapsed = now - this.lastReadCheckTime;
+                if (this.monitorStarted.Value && taskRunner != null)
+                {
+                    this.asyncTasks.Wakeup();
+                }
+            }
+            else
+            {
+                Tracer.DebugFormat("InactivityMonitor[{0}]: Message sent since last write check. Resetting flag.", instanceId);
+            }
 
-			if(!AllowReadCheck(elapsed))
-			{
-				Tracer.Debug("InactivityMonitor[" + instanceId + "]: A read check is not currently allowed.");
-				return;
-			}
+            commandSent.Value = false;
+        }
+        #endregion
 
-			this.lastReadCheckTime = now;
+        #region ReadCheck Related
+        public void ReadCheck()
+        {
+            DateTime now = DateTime.Now;
+            TimeSpan elapsed = now - this.lastReadCheckTime;
+            CompositeTaskRunner taskRunner = this.asyncTasks;
 
-			if(this.inRead.Value || this.failed.Value)
-			{
-				Tracer.DebugFormat("InactivityMonitor[{0}]: A receive is in progress or already failed.", instanceId);
-				return;
-			}
+            if(!AllowReadCheck(elapsed))
+            {
+                Tracer.Debug("InactivityMonitor[" + instanceId + "]: A read check is not currently allowed.");
+                return;
+            }
 
-			if(!commandReceived.Value)
-			{
-				Tracer.DebugFormat("InactivityMonitor[{0}]: No message received since last read check! Sending an InactivityException!", instanceId);
-				if(null != this.asyncErrorTask)
-				{
-					this.asyncErrorTask.IsPending = true;
-				}
+            this.lastReadCheckTime = now;
 
-				this.asyncTasks.Wakeup();
-			}
-			else
-			{
-				commandReceived.Value = false;
-			}
-		}
+            if(this.inRead.Value || this.failed.Value)
+            {
+                Tracer.DebugFormat("InactivityMonitor[{0}]: A receive is in progress or already failed.", instanceId);
+                return;
+            }
 
-		/// <summary>
-		/// Checks if we should allow the read check(if less than 90% of the read
-		/// check time elapsed then we dont do the readcheck
-		/// </summary>
-		/// <param name="elapsed"></param>
-		/// <returns></returns>
-		public bool AllowReadCheck(TimeSpan elapsed)
-		{
-			return (elapsed.TotalMilliseconds > (readCheckTime * 9 / 10));
-		}
-		#endregion
+            if(!commandReceived.Value)
+            {
+                Tracer.DebugFormat("InactivityMonitor[{0}]: No message received since last read check! Sending an InactivityException!", instanceId);
+                if(null != this.asyncErrorTask)
+                {
+                    this.asyncErrorTask.IsPending = true;
+                }
 
-		public override void Stop()
-		{
-			StopMonitorThreads();
-			next.Stop();
-		}
+                if (this.monitorStarted.Value && taskRunner != null)
+                {
+                    this.asyncTasks.Wakeup();
+                }
+            }
+            else
+            {
+                commandReceived.Value = false;
+            }
+        }
 
-		protected override void OnCommand(ITransport sender, Command command)
-		{
-			commandReceived.Value = true;
-			inRead.Value = true;
-			try
-			{
-				if(command.IsKeepAliveInfo)
-				{
-					KeepAliveInfo info = command as KeepAliveInfo;
-					if(info.ResponseRequired)
-					{
-						try
-						{
-							info.ResponseRequired = false;
-							Oneway(info);
-						}
-						catch(IOException ex)
-						{
-							OnException(this, ex);
-						}
-					}
-				}
-				else if(command.IsWireFormatInfo)
-				{
-					lock(monitor)
-					{
-						remoteWireFormatInfo = command as WireFormatInfo;
-						try
-						{
-							StartMonitorThreads();
-						}
-						catch(IOException ex)
-						{
-							OnException(this, ex);
-						}
-					}
-				}
-				base.OnCommand(sender, command);
-			}
-			finally
-			{
-				inRead.Value = false;
-			}
-		}
+        /// <summary>
+        /// Checks if we should allow the read check(if less than 90% of the read
+        /// check time elapsed then we dont do the readcheck
+        /// </summary>
+        /// <param name="elapsed"></param>
+        /// <returns></returns>
+        public bool AllowReadCheck(TimeSpan elapsed)
+        {
+            return (elapsed.TotalMilliseconds > (readCheckTime * 9 / 10));
+        }
+        #endregion
 
-		public override void Oneway(Command command)
-		{
-			// Disable inactivity monitoring while processing a command.
-			// synchronize this method - its not synchronized
-			// further down the transport stack and gets called by more
-			// than one thread  by this class
-			lock(inWrite)
-			{
-				inWrite.Value = true;
-				try
-				{
-					if(failed.Value)
-					{
-						throw new IOException("Channel was inactive for too long: " + next.RemoteAddress.ToString());
-					}
-					if(command.IsWireFormatInfo)
-					{
-						lock(monitor)
-						{
-							localWireFormatInfo = command as WireFormatInfo;
-							StartMonitorThreads();
-						}
-					}
-					next.Oneway(command);
-				}
-				finally
-				{
-					commandSent.Value = true;
-					inWrite.Value = false;
-				}
-			}
-		}
+        public override void Stop()
+        {
+            StopMonitorThreads();
+            next.Stop();
+        }
 
-		protected override void OnException(ITransport sender, Exception command)
-		{
-			if(failed.CompareAndSet(false, true) && !this.disposing)
-			{
-				Tracer.Debug("Exception received in the Inactivity Monitor: " + command.ToString());
-				StopMonitorThreads();
-				base.OnException(sender, command);
-			}
-		}
+        protected override void OnCommand(ITransport sender, Command command)
+        {
+            commandReceived.Value = true;
+            inRead.Value = true;
+            try
+            {
+                if(command.IsKeepAliveInfo)
+                {
+                    KeepAliveInfo info = command as KeepAliveInfo;
+                    if(info.ResponseRequired)
+                    {
+                        try
+                        {
+                            info.ResponseRequired = false;
+                            Oneway(info);
+                        }
+                        catch(IOException ex)
+                        {
+                            OnException(this, ex);
+                        }
+                    }
+                }
+                else if(command.IsWireFormatInfo)
+                {
+                    lock(monitor)
+                    {
+                        remoteWireFormatInfo = command as WireFormatInfo;
+                        try
+                        {
+                            StartMonitorThreads();
+                        }
+                        catch(IOException ex)
+                        {
+                            OnException(this, ex);
+                        }
+                    }
+                }
+                base.OnCommand(sender, command);
+            }
+            finally
+            {
+                inRead.Value = false;
+            }
+        }
 
-		private void StartMonitorThreads()
-		{
-			lock(monitor)
-			{
-				if(this.IsDisposed || this.disposing)
-				{
-					return;
-				}
+        public override void Oneway(Command command)
+        {
+            // Disable inactivity monitoring while processing a command.
+            // synchronize this method - its not synchronized
+            // further down the transport stack and gets called by more
+            // than one thread  by this class
+            lock(inWrite)
+            {
+                inWrite.Value = true;
+                try
+                {
+                    if(failed.Value)
+                    {
+                        throw new IOException("Channel was inactive for too long: " + next.RemoteAddress.ToString());
+                    }
+                    if(command.IsWireFormatInfo)
+                    {
+                        lock(monitor)
+                        {
+                            localWireFormatInfo = command as WireFormatInfo;
+                            StartMonitorThreads();
+                        }
+                    }
+                    next.Oneway(command);
+                }
+                finally
+                {
+                    commandSent.Value = true;
+                    inWrite.Value = false;
+                }
+            }
+        }
 
-				if(monitorStarted.Value)
-				{
-					return;
-				}
+        protected override void OnException(ITransport sender, Exception command)
+        {
+            if(failed.CompareAndSet(false, true) && !this.disposing)
+            {
+                Tracer.Debug("Exception received in the Inactivity Monitor: " + command.ToString());
+                StopMonitorThreads();
+                base.OnException(sender, command);
+            }
+        }
 
-				if(localWireFormatInfo == null)
-				{
-					return;
-				}
+        private void StartMonitorThreads()
+        {
+            lock(monitor)
+            {
+                if(this.IsDisposed || this.disposing)
+                {
+                    return;
+                }
 
-				if(remoteWireFormatInfo == null)
-				{
-					return;
-				}
+                if(monitorStarted.Value)
+                {
+                    return;
+                }
 
-				readCheckTime =
-					Math.Min(
-						localWireFormatInfo.MaxInactivityDuration,
-						remoteWireFormatInfo.MaxInactivityDuration);
-				initialDelayTime = remoteWireFormatInfo.MaxInactivityDurationInitialDelay > 0 ?
-					Math.Min(localWireFormatInfo.MaxInactivityDurationInitialDelay,
-						     remoteWireFormatInfo.MaxInactivityDurationInitialDelay) :
+                if(localWireFormatInfo == null)
+                {
+                    return;
+                }
+
+                if(remoteWireFormatInfo == null)
+                {
+                    return;
+                }
+
+                readCheckTime =
+                    Math.Min(
+                        localWireFormatInfo.MaxInactivityDuration,
+                        remoteWireFormatInfo.MaxInactivityDuration);
+                initialDelayTime = remoteWireFormatInfo.MaxInactivityDurationInitialDelay > 0 ?
+                    Math.Min(localWireFormatInfo.MaxInactivityDurationInitialDelay,
+                             remoteWireFormatInfo.MaxInactivityDurationInitialDelay) :
                     localWireFormatInfo.MaxInactivityDurationInitialDelay;
 
-				if(readCheckTime > 0)
-				{
-					Tracer.DebugFormat("InactivityMonitor[{0}]: Read Check time interval: {1}",
-								   instanceId, readCheckTime);
-					Tracer.DebugFormat("InactivityMonitor[{0}]: Initial Delay time interval: {1}",
-									   instanceId, initialDelayTime);
+                if(readCheckTime > 0)
+                {
+                    Tracer.DebugFormat("InactivityMonitor[{0}]: Read Check time interval: {1}",
+                                   instanceId, readCheckTime);
+                    Tracer.DebugFormat("InactivityMonitor[{0}]: Initial Delay time interval: {1}",
+                                       instanceId, initialDelayTime);
 
-					monitorStarted.Value = true;
-					this.asyncTasks = new CompositeTaskRunner("InactivityMonitor[" + instanceId + "].Runner");
+                    monitorStarted.Value = true;
+                    this.asyncTasks = new CompositeTaskRunner("InactivityMonitor[" + instanceId + "].Runner");
 
-					this.asyncErrorTask = new AsyncSignalReadErrorkTask(this, next.RemoteAddress);
-					this.asyncWriteTask = new AsyncWriteTask(this);
+                    this.asyncErrorTask = new AsyncSignalReadErrorkTask(this, next.RemoteAddress);
+                    this.asyncWriteTask = new AsyncWriteTask(this);
 
-					this.asyncTasks.AddTask(this.asyncErrorTask);
-					this.asyncTasks.AddTask(this.asyncWriteTask);
+                    this.asyncTasks.AddTask(this.asyncErrorTask);
+                    this.asyncTasks.AddTask(this.asyncWriteTask);
 
-					writeCheckTime = readCheckTime > 3 ? readCheckTime / 3 : readCheckTime;
+                    writeCheckTime = readCheckTime > 3 ? readCheckTime / 3 : readCheckTime;
 
-					Tracer.DebugFormat("InactivityMonitor[{0}]: Write Check time interval: {1}",
-									   instanceId, writeCheckTime);
+                    Tracer.DebugFormat("InactivityMonitor[{0}]: Write Check time interval: {1}",
+                                       instanceId, writeCheckTime);
 
-					this.connectionCheckTimer = new Timer(
-						new TimerCallback(CheckConnection),
-						null,
-						initialDelayTime,
-						writeCheckTime
-						);
-				}
-			}
-		}
+                    this.connectionCheckTimer = new Timer(
+                        new TimerCallback(CheckConnection),
+                        null,
+                        initialDelayTime,
+                        writeCheckTime);
+                }
+            }
+        }
 
-		private void StopMonitorThreads()
-		{
-			lock(monitor)
-			{
-				if(monitorStarted.CompareAndSet(true, false))
-				{
-					AutoResetEvent shutdownEvent = new AutoResetEvent(false);
+        private void StopMonitorThreads()
+        {
+            lock(monitor)
+            {
+                if(monitorStarted.CompareAndSet(true, false))
+                {
+                    AutoResetEvent shutdownEvent = new AutoResetEvent(false);
 
-					if(null != connectionCheckTimer)
-					{
-						// Attempt to wait for the Timer to shutdown, but don't wait
-						// forever, if they don't shutdown after two seconds, just quit.
-						this.connectionCheckTimer.Dispose(shutdownEvent);
-						if(!shutdownEvent.WaitOne(TimeSpan.FromMilliseconds(3000), false))
-						{
-							Tracer.WarnFormat("InactivityMonitor[{0}]: Timer Task didn't shutdown properly.", instanceId);
-						}
+                    if(null != connectionCheckTimer)
+                    {
+                        // Attempt to wait for the Timer to shutdown, but don't wait
+                        // forever, if they don't shutdown after a few seconds, just quit.
+                        this.connectionCheckTimer.Dispose(shutdownEvent);
+                        if(!shutdownEvent.WaitOne(TimeSpan.FromMilliseconds(5000), false))
+                        {
+                            Tracer.WarnFormat("InactivityMonitor[{0}]: Timer Task didn't shutdown properly.", instanceId);
+                        }
 
-						this.connectionCheckTimer = null;
-					}
+                        this.connectionCheckTimer = null;
+                    }
 
-					if(null != this.asyncTasks)
-					{
-						this.asyncTasks.RemoveTask(this.asyncWriteTask);
-						this.asyncTasks.RemoveTask(this.asyncErrorTask);
+                    if(null != this.asyncTasks)
+                    {
+                        this.asyncTasks.RemoveTask(this.asyncWriteTask);
+                        this.asyncTasks.RemoveTask(this.asyncErrorTask);
 
-						this.asyncTasks.Shutdown();
-						this.asyncTasks = null;
-					}
+                        this.asyncTasks.Shutdown();
+                        this.asyncTasks = null;
+                    }
 
-					this.asyncWriteTask = null;
-					this.asyncErrorTask = null;
-				}
-			}
+                    this.asyncWriteTask = null;
+                    this.asyncErrorTask = null;
+                }
+            }
 
-			Tracer.DebugFormat("InactivityMonitor[{0}]: Stopped Monitor Threads.", instanceId);
-		}
+            Tracer.DebugFormat("InactivityMonitor[{0}]: Stopped Monitor Threads.", instanceId);
+        }
 
-		#region Async Tasks
-		// Task that fires when the TaskRunner is signaled by the ReadCheck Timer Task.
-		class AsyncSignalReadErrorkTask : CompositeTask
-		{
-			private readonly InactivityMonitor parent;
-			private readonly Uri remote;
-			private readonly Atomic<bool> pending = new Atomic<bool>(false);
+        #region Async Tasks
+        // Task that fires when the TaskRunner is signaled by the ReadCheck Timer Task.
+        class AsyncSignalReadErrorkTask : CompositeTask
+        {
+            private readonly InactivityMonitor parent;
+            private readonly Uri remote;
+            private readonly Atomic<bool> pending = new Atomic<bool>(false);
 
-			public AsyncSignalReadErrorkTask(InactivityMonitor parent, Uri remote)
-			{
-				this.parent = parent;
-				this.remote = remote;
-			}
+            public AsyncSignalReadErrorkTask(InactivityMonitor parent, Uri remote)
+            {
+                this.parent = parent;
+                this.remote = remote;
+            }
 
-			public bool IsPending
-			{
-				get { return this.pending.Value; }
-				set { this.pending.Value = value; }
-			}
+            public bool IsPending
+            {
+                get { return this.pending.Value; }
+                set { this.pending.Value = value; }
+            }
 
-			public bool Iterate()
-			{
-				if(this.pending.CompareAndSet(true, false) && this.parent.monitorStarted.Value)
-				{
-					IOException ex = new IOException("Channel was inactive for too long: " + remote);
-					this.parent.OnException(parent, ex);
-				}
+            public bool Iterate()
+            {
+                if(this.pending.CompareAndSet(true, false) && this.parent.monitorStarted.Value)
+                {
+                    IOException ex = new IOException("Channel was inactive for too long: " + remote);
+                    this.parent.OnException(parent, ex);
+                }
 
-				return this.pending.Value;
-			}
-		}
+                return this.pending.Value;
+            }
+        }
 
-		// Task that fires when the TaskRunner is signaled by the WriteCheck Timer Task.
-		class AsyncWriteTask : CompositeTask
-		{
-			private readonly InactivityMonitor parent;
-			private readonly Atomic<bool> pending = new Atomic<bool>(false);
+        // Task that fires when the TaskRunner is signaled by the WriteCheck Timer Task.
+        class AsyncWriteTask : CompositeTask
+        {
+            private readonly InactivityMonitor parent;
+            private readonly Atomic<bool> pending = new Atomic<bool>(false);
 
-			public AsyncWriteTask(InactivityMonitor parent)
-			{
-				this.parent = parent;
-			}
+            public AsyncWriteTask(InactivityMonitor parent)
+            {
+                this.parent = parent;
+            }
 
-			public bool IsPending
-			{
-				get { return this.pending.Value; }
-				set { this.pending.Value = value; }
-			}
+            public bool IsPending
+            {
+                get { return this.pending.Value; }
+                set { this.pending.Value = value; }
+            }
 
-			public bool Iterate()
-			{
-				Tracer.DebugFormat("InactivityMonitor[{0}] preparing for another Write Check", parent.instanceId);
-				if(this.pending.CompareAndSet(true, false) && this.parent.monitorStarted.Value)
-				{
-					try
-					{
-						Tracer.DebugFormat("InactivityMonitor[{0}] Write Check required sending KeepAlive.",
-										   parent.instanceId);
-						KeepAliveInfo info = new KeepAliveInfo();
-						info.ResponseRequired = this.parent.keepAliveResponseRequired.Value;
-						this.parent.Oneway(info);
-					}
-					catch(IOException e)
-					{
-						this.parent.OnException(parent, e);
-					}
-				}
+            public bool Iterate()
+            {
+                Tracer.DebugFormat("InactivityMonitor[{0}] preparing for another Write Check", parent.instanceId);
+                if(this.pending.CompareAndSet(true, false) && this.parent.monitorStarted.Value)
+                {
+                    try
+                    {
+                        Tracer.DebugFormat("InactivityMonitor[{0}] Write Check required sending KeepAlive.",
+                                           parent.instanceId);
+                        KeepAliveInfo info = new KeepAliveInfo();
+                        info.ResponseRequired = this.parent.keepAliveResponseRequired.Value;
+                        this.parent.Oneway(info);
+                    }
+                    catch(IOException e)
+                    {
+                        this.parent.OnException(parent, e);
+                    }
+                }
 
-				return this.pending.Value;
-			}
-		}
-		#endregion
-	}
+                return this.pending.Value;
+            }
+        }
+        #endregion
+    }
 
 }
