private WaitCallback ProcessBlock(ManagedBufferBlock block, WaitHandle terminateThread, EventWaitHandle threadActivated, EventWaitHandle threadTerminated) { return(state => { var processEvents = new [] { block.CommunicationBlock.ProfilerRequestsInformation, block.MemoryBlock.ProfilerHasResults, terminateThread }; threadActivated.Set(); while (block.Active) { switch (WaitHandle.WaitAny(processEvents)) { case 0: _communicationManager.HandleCommunicationBlock(block.CommunicationBlock, b => { }); break; case 1: var data = _communicationManager.HandleMemoryBlock(block.MemoryBlock); // don't let the queue get too big as using too much memory causes // problems i.e. the target process closes down but the host takes // ages to shutdown; this is a compromise. _messageQueue.Enqueue(data); if (_messageQueue.Count > 400) { do { Thread.Yield(); } while (_messageQueue.Count > 200); } break; case 2: threadTerminated.Set(); return; } } threadTerminated.Set(); _memoryManager.RemoveDeactivatedBlocks(); }); }