示例#1
0
        void OnExecutor_ProcessItemCompleted(ThreadExecutor <T> source, ThreadExecutorItem <T> item)
        {
            ModuleProc PROC = new ModuleProc(DYN_MODULE_NAME, "OnExecutor_ProcessItemCompleted");

            try
            {
                lock (_lockList)
                {
                    try
                    {
                        Interlocked.Decrement(ref _activeWorkers);
                        this.ActiveWorkerThreadDecrement(source.UniqueKey, item.UniqueKey);
                    }
                    catch (Exception ex)
                    {
                        Log.Exception(PROC, ex);
                    }
                }

                // wake the producers who are waiting to produce
                if (_fullWaiters > 0)
                {
                    lock (_lockFullEvent)
                    {
                        Monitor.Pulse(_lockFullEvent);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }
        }
示例#2
0
        private ThreadExecutor <T> AddThreadExecutor(string itemKey)
        {
            ModuleProc         PROC     = new ModuleProc(DYN_MODULE_NAME, "Initialize");
            ThreadExecutor <T> executor = null;

            try
            {
                IThreadSafeQueue <ThreadExecutorItem <T> > threadQueue = null;

                if (_kernelModeQueue)
                {
                    threadQueue = new BlockingBoundQueueKernel <ThreadExecutorItem <T> >(this.ThreadExecutorService, this.QueueCapacity);
                }
                else
                {
                    threadQueue = new BlockingBoundQueueUser <ThreadExecutorItem <T> >(this.ThreadExecutorService, this.QueueCapacity);
                }

                executor                       = new ThreadExecutor <T>(this.ThreadExecutorService, threadQueue, false, itemKey);
                executor.ProcessItem          += new ExecutorProcessItemHandler <T>(OnExecutor_ProcessItem);
                executor.ProcessItemCompleted += new ExecutorProcessItemCompletedHandler <T>(OnExecutor_ProcessItemCompleted);
                _activeWorkersCount.Add(itemKey, new ThreadHashValue()
                {
                    Executor  = executor,
                    ItemCount = 0
                });
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }

            return(executor);
        }
示例#3
0
        private void DoWorkItem(ThreadExecutor <T> executor, T item)
        {
            ModuleProc PROC = new ModuleProc(DYN_MODULE_NAME, "DoWorkItem");

            try
            {
                if (!item.Equals(default(T)))
                {
                    try
                    {
                        if (executor != null)
                        {
                            ThreadExecutorItem <T> executorItem = new ThreadExecutorItem <T>(item);
                            executor.QueueWorkerItem(executorItem);
                            Interlocked.Increment(ref _activeWorkers);
                            this.ActiveWorkerThreadIncrement(executor.UniqueKey, item.UniqueKey);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Exception(PROC, ex);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }
        }
 public int CompareTo(ThreadExecutor <T> other)
 {
     if (other == null)
     {
         return(1);
     }
     return(string.Compare(_uniqueKey, other._uniqueKey, true));
 }
 protected override bool IsQueueFull(ThreadExecutor <T> executor, T item)
 {
     if (_activeWorkers == this.Capacity)
     {
         return(true);
     }
     return(_activeWorkersCount[executor.UniqueKey].ItemCount == this.QueueCapacity);
 }
示例#6
0
        private ThreadExecutor <T> GetFreeThreadExecutor(T item)
        {
            ModuleProc         PROC     = new ModuleProc(this.DYN_MODULE_NAME, "GetFreeThreadExecutor");
            ThreadExecutor <T> executor = null;

            try
            {
                // executor key free thread approach
                if (item is IExecutorKeyFreeThread)
                {
                    // find the thread with minimum number of items
                    IGrouping <int, KeyValuePair <int, int> > groupedItem = (from i in _workerThreadItems
                                                                             group i by i.Value).OrderBy(i => i.Key).FirstOrDefault();
                    int index = 0;
                    if (groupedItem != null)
                    {
                        index = groupedItem.FirstOrDefault().Key;
                    }

                    if (index >= 0 && index < _workerThreads.Count)
                    {
                        executor = _workerThreads[index];
                        Log.Info(PROC, "Thread " + executor.ContainerIndex.ToString() + " was taken by IExecutorKeyFreeThread approach.");
                        if (_workerThreadItems.ContainsKey(index))
                        {
                            _workerThreadItems[index] = _workerThreadItems[index] + 1;
                        }
                    }
                }

                // executor key thread approach
                if (executor == null &&
                    item is IExecutorKeyThread)
                {
                    int index = ((IExecutorKeyThread)item).GetThreadIndex(this.Capacity);
                    if (index >= 0 && index < _workerThreads.Count)
                    {
                        executor = _workerThreads[index];
                        Log.Info(PROC, "Thread " + executor.ContainerIndex.ToString() + " was taken by ExecutorKeyTheread approach.");
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }
            finally
            {
                // no more free threads
                if (executor == null)
                {
                    executor = _workerThreads[_rnd.Next(0, _workerThreads.Count - 1)];
                    Log.Info(PROC, "Thread " + executor.ContainerIndex.ToString() + " was taken as random.");
                }
            }

            return(executor);
        }
        private void DoWorkItem(T item)
        {
            ModuleProc PROC = new ModuleProc(DYN_MODULE_NAME, "DoWorkItem");

            try
            {
                if (!item.Equals(default(T)))
                {
                    try
                    {
                        if (_workersFree.First != null)
                        {
                            ThreadExecutor <T>             executor       = _workersFree.First.Value;
                            string                         executorKey    = executor.UniqueKey;
                            string                         itemKey        = item.UniqueKey;
                            List <ThreadExecutorItem <T> > workerSequence = null;
                            _workersFree.RemoveFirst();

                            if (!_workersRunning.ContainsKey(executorKey))
                            {
                                _workersRunning.Add(executorKey, executor);
                            }
                            if (!_workerSequences.ContainsKey(itemKey))
                            {
                                _workerSequences.Add(itemKey, new List <ThreadExecutorItem <T> >());
                            }

                            workerSequence = _workerSequences[itemKey];
                            EventWaitHandle wh = null;
                            if (workerSequence.Count > 0)
                            {
                                //wh = new ManualResetEvent(false);
                                wh = executor.QueueSignal;
                                wh.Reset();
                            }

                            ThreadExecutorItem <T> executorItem = new ThreadExecutorItem <T>(item);
                            executorItem.WaitHandle = wh;
                            workerSequence.Add(executorItem);
                            executor.QueueWorkerItem(executorItem);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Exception(PROC, ex);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }
        }
示例#8
0
        private void Initialize(bool checkItemCount)
        {
            ModuleProc PROC = new ModuleProc(DYN_MODULE_NAME, "Initialize");

            try
            {
                _uniqueKey = "QueueThreadsThreadPoolExecutor_" + Guid.NewGuid().ToString();
                Log.InfoV(PROC, "{0} : Capacity : {1:D}, Queue Capacity : {2:D}", _uniqueKey, this.Capacity, this.QueueCapacity);

                this.RegisterForShutdown();
                this.ExecutorService.AddExecutor(this);

                _workerThreads      = new List <ThreadExecutor <T> >();
                _activeWorkersCount = new SortedDictionary <string, ThreadHashValue>(StringComparer.InvariantCultureIgnoreCase);
                _workerThreadItems  = new SortedDictionary <int, int>();
                _rnd = new Random(0);

                for (int i = 0; i < this.Capacity; i++)
                {
                    IThreadSafeQueue <ThreadExecutorItem <T> > threadQueue = null;

                    if (_kernelModeQueue)
                    {
                        threadQueue = new BlockingBoundQueueKernel <ThreadExecutorItem <T> >(this.ThreadExecutorService, this.QueueCapacity);
                    }
                    else
                    {
                        threadQueue = new BlockingBoundQueueUser <ThreadExecutorItem <T> >(this.ThreadExecutorService, this.QueueCapacity);
                    }

                    ThreadExecutor <T> executor = new ThreadExecutor <T>(this.ThreadExecutorService, threadQueue, checkItemCount, string.Empty);
                    executor.ProcessItem          += new ExecutorProcessItemHandler <T>(OnExecutor_ProcessItem);
                    executor.ProcessItemCompleted += new ExecutorProcessItemCompletedHandler <T>(OnExecutor_ProcessItemCompleted);
                    executor.ContainerIndex        = i;
                    _workerThreads.Add(executor);
                    _activeWorkersCount.Add(executor.UniqueKey, new ThreadHashValue()
                    {
                        Executor  = executor,
                        ItemCount = 0
                    });
                    if (!_workerThreadItems.ContainsKey(i))
                    {
                        _workerThreadItems.Add(i, 0);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }
        }
        private void Initialize(bool kernelModeQueue)
        {
            ModuleProc PROC = new ModuleProc(DYN_MODULE_NAME, "Initialize");

            try
            {
                _uniqueKey = "FreeThreadPoolExecutor_" + Guid.NewGuid().ToString();
                this.RegisterForShutdown();
                this.ExecutorService.AddExecutor(this);
                Log.InfoV(PROC, "{0} : Capacity : {1:D}", _uniqueKey, this.Capacity);

                _workersFree     = new LinkedList <ThreadExecutor <T> >();
                _workersRunning  = new SortedDictionary <string, ThreadExecutor <T> >(StringComparer.InvariantCultureIgnoreCase);
                _workerSequences = new SortedDictionary <string, List <ThreadExecutorItem <T> > >(StringComparer.InvariantCultureIgnoreCase);

                for (int i = 0; i < this.Capacity; i++)
                {
                    IThreadSafeQueue <ThreadExecutorItem <T> > threadQueue = null;

                    if (kernelModeQueue)
                    {
                        threadQueue = new BlockingBoundQueueKernel <ThreadExecutorItem <T> >(this.ExecutorService, 1);
                    }
                    else
                    {
                        threadQueue = new BlockingBoundQueueUser <ThreadExecutorItem <T> >(this.ExecutorService, 1);
                    }

                    ThreadExecutor <T> executor = new ThreadExecutor <T>(this.ExecutorService, threadQueue);
                    executor.ProcessItem          += new ExecutorProcessItemHandler <T>(OnExecutor_ProcessItem);
                    executor.ProcessItemCompleted += new ExecutorProcessItemCompletedHandler <T>(OnExecutor_ProcessItemCompleted);
                    _workersFree.AddLast(new LinkedListNode <ThreadExecutor <T> >(executor));
                }
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }
        }
示例#10
0
        public override void QueueWorkerItem(T item)
        {
            ModuleProc         PROC     = new ModuleProc(DYN_MODULE_NAME, "QueueWorkerItem");
            ThreadExecutor <T> executor = null;

            if (this.ExecutorService.IsShutdown)
            {
                return;
            }
            string itemKey = string.Empty;

            lock (_lockList)
            {
                try
                {
                    if (!item.Equals(default(T)))
                    {
                        // find the executor
                        itemKey = item.UniqueKey;
                        if (_itemWorkerThreads.ContainsKey(itemKey))
                        {
                            executor = _itemWorkerThreads[itemKey];
                        }
                        else
                        {
                            executor = this.GetFreeThreadExecutor(item);
                            Log.Info(PROC, string.Format("Found Thread Index : {0:D} for item key : {1}", executor.ContainerIndex, itemKey));
                            _itemWorkerThreads.Add(itemKey, executor);
                        }
                    }

                    if (executor != null)
                    {
                        // if full, wait until some items consumed
                        while (this.IsQueueFull(executor, item))
                        {
                            Log.Description(PROC, "Queue is full. Thread pool is blocked for : " + itemKey);
                            if (this.ExecutorService.IsShutdown)
                            {
                                break;
                            }
                            _fullWaiters++;

                            try
                            {
                                lock (_lockFullEvent)
                                {
                                    Monitor.Exit(_lockList);
                                    Log.Debug(PROC, "Locked : " + _uniqueKey);
                                    Monitor.Wait(_lockFullEvent);
                                    Log.Debug(PROC, "Unlocked : " + _uniqueKey);
                                    Monitor.Enter(_lockList);
                                }
                            }
                            finally
                            {
                                _fullWaiters--;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Exception(PROC, ex);
                }
                finally
                {
                    if (!this.ExecutorService.IsShutdown)
                    {
                        this.DoWorkItem(executor, item);
                    }
                }
            }
        }
示例#11
0
 protected abstract bool IsQueueFull(ThreadExecutor <T> executor, T item);
示例#12
0
 protected virtual bool IsQueueFull(ThreadExecutor <T> executor, T item)
 {
     return(_activeWorkersCount[item.UniqueKey].ItemCount == this.QueueCapacity);
 }
        void OnExecutor_ProcessItemCompleted(ThreadExecutor <T> source, ThreadExecutorItem <T> item)
        {
            ModuleProc PROC = new ModuleProc(DYN_MODULE_NAME, "OnExecutor_ProcessItemCompleted");

            try
            {
                lock (_lockList)
                {
                    try
                    {
                        string executorKey = source.UniqueKey;
                        string itemKey     = item.UniqueKey;

                        if (_workersRunning.ContainsKey(executorKey))
                        {
                            ThreadExecutor <T> executor = _workersRunning[executorKey];
                            if (source == executor)
                            {
                                _workersRunning.Remove(executorKey);
                                _workersFree.AddLast(executor);

                                if (_workerSequences.ContainsKey(itemKey))
                                {
                                    List <ThreadExecutorItem <T> > workerSequence = _workerSequences[itemKey];
                                    if (workerSequence.Count > 0)
                                    {
                                        ThreadExecutorItem <T> sequenceItem = workerSequence[0];
                                        EventWaitHandle        wh           = sequenceItem.WaitHandle;

                                        if (wh != null)
                                        {
                                            //wh.Close();
                                            //wh = null;
                                            wh.Reset();
                                        }
                                        workerSequence.RemoveAt(0);

                                        if (workerSequence.Count > 0)
                                        {
                                            wh = workerSequence[0].WaitHandle;
                                            if (wh != null)
                                            {
                                                wh.Set();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Exception(PROC, ex);
                    }
                }

                // wake the producers who are waiting to produce
                if (_fullWaiters > 0)
                {
                    lock (_lockFullEvent)
                    {
                        Monitor.Pulse(_lockFullEvent);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(PROC, ex);
            }
        }