Ejemplo n.º 1
0
        private void ProcessWorkItems(object state)
        {
            long     lastWork    = Stopwatch.GetTimestamp();
            TimeSpan maxIdleTime = TimeSpan.FromTicks(MaxIdleTimeInTicks);

            while (true)
            {
                Action workItem       = null;
                var    lockTaken      = false;
                bool   idleForTooLong = Utilities.ConvertRawToTimestamp(Stopwatch.GetTimestamp() - lastWork) < maxIdleTime;
                try
                {
                    spinLock.Enter(ref lockTaken);

                    if (workItems.Count > 0)
                    {
                        workItem = workItems.Dequeue();
                        if (workItems.Count == 0)
                        {
                            workAvailable.Reset();
                        }
                    }
                    else if (idleForTooLong)
                    {
                        aliveCount--;
                        return;
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        spinLock.Exit(true);
                    }
                }

                if (workItem != null)
                {
                    Interlocked.Increment(ref workingCount);
                    try
                    {
                        workItem.Invoke();
                    }
                    catch (Exception)
                    {
                        // Ignoring Exception
                    }
                    Interlocked.Decrement(ref workingCount);
                    PooledDelegateHelper.Release(workItem);
                    lastWork = Stopwatch.GetTimestamp();
                }

                // Wait for another work item to be (potentially) available
                workAvailable.WaitOne(maxIdleTime);
            }
        }
Ejemplo n.º 2
0
        private void ProcessWorkItems()
        {
            while (true)
            {
                Action workItem  = null;
                var    lockTaken = false;
                try
                {
                    spinLock.Enter(ref lockTaken);
                    int workItemCount = workItems.Count;

                    if (workItemCount > 0)
                    {
                        workItem = workItems.Dequeue();
                        if (workItemCount == 1)
                        {
                            workAvailable.Reset();                     // we must have taken off our last item
                        }
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        spinLock.Exit(true);
                    }
                }

                if (workItem != null)
                {
                    Interlocked.Increment(ref workingCount);
                    try
                    {
                        workItem.Invoke();
                    }
                    catch (Exception)
                    {
                        // Ignoring Exception
                    }
                    Interlocked.Decrement(ref workingCount);
                    PooledDelegateHelper.Release(workItem);
                }

                // Wait for another work item to be (potentially) available
                if (workAvailable.WaitOne(maxIdleTime) == false)
                {
                    aliveCount--;
                    return;
                }
            }
        }
Ejemplo n.º 3
0
        private void ProcessWorkItems()
        {
            while (true)
            {
                Action workItem  = null;
                var    lockTaken = false;
                int    workItemCount;
                try
                {
                    spinLock.Enter(ref lockTaken);
                    workItemCount = workItems.Count;

                    if (workItemCount > 0)
                    {
                        workItem = workItems.Dequeue();
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        spinLock.Exit(true);
                    }
                }

                // do we have a job to do?
                if (workItem != null)
                {
                    try
                    {
                        workItem.Invoke();
                    }
                    catch (Exception)
                    {
                        // Ignoring Exception
                    }
                    PooledDelegateHelper.Release(workItem);
                }

                // only reset and wait if we took our last job
                if (workItemCount <= 1)
                {
                    workAvailable.WaitOne();
                }
            }
        }
Ejemplo n.º 4
0
        private void ProcessWorkItems()
        {
            while (true)
            {
                Action workItem  = null;
                var    lockTaken = false;
                try
                {
                    spinLock.Enter(ref lockTaken);

                    if (workItems.Count > 0)
                    {
                        workItem = workItems.Dequeue();
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        spinLock.Exit(true);
                    }
                }

                // do we have a job to do?
                if (workItem != null)
                {
                    try
                    {
                        workItem.Invoke();
                    }
                    catch (Exception)
                    {
                        // Ignoring Exception
                    }
                    PooledDelegateHelper.Release(workItem);
                }
                // couldn't find work, wait until some more is available
                else
                {
                    workAvailable.WaitOne();
                }
            }
        }
Ejemplo n.º 5
0
        private void ProcessWorkItems()
        {
            Interlocked.Decrement(ref busyCount);
            try
            {
                long lastWorkTS = Stopwatch.GetTimestamp();
                while (true)
                {
                    Action workItem  = null;
                    bool   lockTaken = false;
                    try
                    {
                        spinLock.Enter(ref lockTaken);
                        if (workItems.Count > 0)
                        {
                            workItem = workItems.Dequeue();
                            if (workItems.Count == 0)
                            {
                                workAvailable.Reset();
                            }
                        }
                    }
                    finally
                    {
                        if (lockTaken)
                        {
                            spinLock.Exit(true);
                        }
                    }

                    if (workItem == null)
                    {
                        bool idleForTooLong = Stopwatch.GetTimestamp() - lastWorkTS > MaxIdleTimeTS;
                        // Wait for another work item to be (potentially) available
                        if (idleForTooLong || workAvailable.WaitOne(MaxIdleTimeInMS) == false)
                        {
                            // No work given in the last MaxIdleTimeTS, close this task
                            return;
                        }
                    }
                    else
                    {
                        Interlocked.Increment(ref busyCount);
                        try
                        {
                            workItem();
                        }
                        // Let exceptions fall into unhandled as we don't have any
                        // good mechanisms to pass it elegantly over to user-land yet
                        finally
                        {
                            Interlocked.Decrement(ref busyCount);
                        }
                        PooledDelegateHelper.Release(workItem);
                        lastWorkTS = Stopwatch.GetTimestamp();
                    }
                }
            }
            finally
            {
                Interlocked.Decrement(ref aliveCount);
            }
        }
Ejemplo n.º 6
0
        private void ProcessWorkItems(object state)
        {
            //var spinWait = new SpinWait();

            while (true)
            {
                Action workItem = null;

                //while (!spinWait.NextSpinWillYield)
                {
                    var lockTaken = false;
                    try
                    {
                        spinLock.Enter(ref lockTaken);

                        if (workItems.Count > 0)
                        {
                            try
                            {
                                workItem = workItems.Dequeue();
                                //Interlocked.Increment(ref activeThreadCount);

                                if (workItems.Count == 0)
                                {
                                    workAvailable.Reset();
                                }
                            }
                            catch
                            {
                            }
                        }

                        //if (workItems.Count > 0)
                        //{
                        //    // If we didn't consume the last work item, kick off another worker
                        //    workAvailable.Set();
                        //}
                    }
                    finally
                    {
                        if (lockTaken)
                        {
                            spinLock.Exit(true);
                        }
                    }

                    if (workItem != null)
                    {
                        try
                        {
                            Interlocked.Increment(ref activeThreadCount);
                            workItem.Invoke();

                            //spinWait.Reset();
                        }
                        catch (Exception)
                        {
                            // Ignoring Exception
                        }
                        finally
                        {
                            PooledDelegateHelper.Release(workItem);
                            Interlocked.Decrement(ref activeThreadCount);
                        }
                    }
                    else
                    {
                        //spinWait.SpinOnce();
                    }
                }

                // Wait for another work item to be (potentially) available
                workAvailable.WaitOne();
            }
        }
Ejemplo n.º 7
0
        private void ProcessWorkItems(object nodeObj)
        {
            // nodeObj is non-null when a thread caught an exception and had to throw,
            // the thread created another one and passed its node obj to us.
            LinkedIdleThread node = nodeObj == null ? new LinkedIdleThread(new ManualResetEventSlim(true)) : (LinkedIdleThread)nodeObj;

            try
            {
                while (true)
                {
                    Action     action;
                    LinkedWork workNode = sharedWorkStack;
                    if (workNode != null)
                    {
                        if (TryTakeFromSharedNonBlocking(out var tempAction, workNode))
                        {
                            action = tempAction;
                        }
                        else
                        {
                            // We have shared work to do but failed to retrieve it, try again
                            continue;
                        }
                    }
                    else
                    {
                        // Should we notify system that this thread is ready to work?
                        // This has to also work for when a thread takes the place of another one when restoring
                        // from an exception for example.
                        // If the mre was set and we took the work, this node definitely is dequeued, re-queue it
                        if (node.MRE.IsSet && Volatile.Read(ref node.Work) == null)
                        {
                            // Notify that we're waiting for work
                            node.MRE.Reset();
                            node.PreviousIsValid = false;
                            node.Previous        = Interlocked.Exchange(ref idleThreads, node);
                            node.PreviousIsValid = true;
                        }

                        // Wait for work
                        SpinWait sw = new SpinWait();
                        while (true)
                        {
                            if (node.MRE.IsSet)
                            {
                                // Work has been scheduled for this thread specifically, take it
                                action = Interlocked.Exchange(ref node.Work, null);
                                break;
                            }
                            if (TryTakeFromSharedNonBlocking(out var tempAction, sharedWorkStack))
                            {
                                action = tempAction;
                                break;                                 // We successfully dequeued this node from the shared stack, quit loop and process action
                            }

                            // Wait for work
                            if (sw.NextSpinWillYield)
                            {
                                // Wait for work to be scheduled specifically to this thread
                                node.MRE.Wait();
                                action = Interlocked.Exchange(ref node.Work, null);
                                break;
                            }

                            sw.SpinOnce();
                        }
                    }

                    try
                    {
                        action();
                    }
                    finally
                    {
                        PooledDelegateHelper.Release(action);
                    }
                }
            }
            finally
            {
                // We must keep up the amount of threads that the system handles.
                // Spawn a new one as this one is about to abort because of an exception.
                NewThread(node);
            }
        }
Ejemplo n.º 8
0
        private void ProcessWorkItems(object paramObj)
        {
            try
            {
                while (true)
                {
                    Action action;
                    var    sw = new SpinWait();
                    while (true)
                    {
                        if (queue.TryDequeue(out action))
                        {
                            break;
                        }

                        if (Volatile.Read(ref itemCount) == 0)
                        {
                            if (sw.NextSpinWillYield)
                            {
                                bool reset = false;
                                lock (lockObj)
                                {
                                    if (Volatile.Read(ref itemCount) == 0)
                                    {
                                        Interlocked.Increment(ref idleCount);
                                        Monitor.Wait(lockObj);
                                        // We've got work to deal with, pulse other threads
                                        Monitor.Pulse(lockObj);
                                        reset = true;
                                    }
                                }

                                if (reset)
                                {
                                    Interlocked.Decrement(ref idleCount);
                                    sw = new SpinWait();
                                }
                            }
                            else
                            {
                                // Spin for a while to catch more incoming work
                                sw.SpinOnce();
                            }
                        }
                    }

                    Interlocked.Decrement(ref itemCount);
                    try
                    {
                        action();
                    }
                    finally
                    {
                        PooledDelegateHelper.Release(action);
                    }
                }
            }
            finally
            {
                // We must keep up the amount of threads that the system handles.
                // Spawn a new one as this one is about to abort because of an exception.
                NewThread();
            }
        }