예제 #1
0
        private void ProcessMessages(WaitHandle[] handles)
        {
            var threadHandles = new List <ThreadTermination>();

            do
            {
                switch (WaitHandle.WaitAny(handles))
                {
                case 0:
                    _continueWait = false;
                    break;

                case 1:
                    _communicationManager.HandleCommunicationBlock(_mcb,
                                                                   block => Task.Factory.StartNew(() =>
                    {
                        lock (SyncRoot)
                        {
                            threadHandles.Add(StartProcessingThread(block));
                        }
                    }));
                    break;

                default:
                    break;
                }
            } while (_continueWait);

            _memoryManager.WaitForBlocksToClose(BufferWaitCount);

            _memoryManager.FetchRemainingBufferData(data => _messageQueue.Enqueue(data));

            lock (SyncRoot)
            {
                if (threadHandles.Any())
                {
                    var tasks = threadHandles
                                .Select((e, index) => new { ThreadTermination = e, Block = index / NumHandlesPerBlock })
                                .GroupBy(g => g.Block)
                                .Select(g => g.Select(a => a.ThreadTermination).ToList())
                                .Select(g => Task.Factory.StartNew(() =>
                    {
                        ConsumeException(() =>
                        {
                            g.Select(h => h.CancelThreadEvent).ToList().ForEach(h => h.Set());
                            WaitHandle.WaitAll(g.Select(h => h.ThreadFinishedEvent).ToArray <WaitHandle>(),
                                               new TimeSpan(0, 0, 20));
                        });
                    })).ToArray();

                    Task.WaitAll(tasks);

                    threadHandles.Clear();
                }
            }

            _messageQueue.Enqueue(new byte[0]);
        }