Exemple #1
0
        public bool DoWork(int expectedID)
        {
            using (executionLock.AcquireExclusiveUsing())
            {
                if (expectedID < runCount)
                {
                    return(true);
                }
                if (work == null)
                {
                    return(false);
                }
                if (executing == work.Options.MaximumThreads)
                {
                    return(false);
                }
                executing++;
            }

            // associate the current task with this thread, so that Task.CurrentTask gives the correct result
            Stack <Task> tasks = null;

            if (!runningTasks.TryGet(Thread.CurrentThread, out tasks))
            {
                tasks = new Stack <Task>();
                runningTasks.Add(Thread.CurrentThread, tasks);
            }
            tasks.Push(new Task(this));

            // execute the task
            try
            {
                // Set work data to running if able
                if (WorkData != null)
                {
                    WorkData.WorkState = ParallelTasks.WorkData.WorkStateEnum.RUNNING;
                }

                work.DoWork(WorkData);

                // Set work data to succeeded if able and not failed
                if (WorkData != null && WorkData.WorkState == ParallelTasks.WorkData.WorkStateEnum.RUNNING)
                {
                    WorkData.WorkState = ParallelTasks.WorkData.WorkStateEnum.SUCCEEDED;
                }
            }
            catch (Exception e)
            {
                if (exceptionBuffer == null)
                {
                    var newExceptions = new List <Exception>();
                    Interlocked.CompareExchange(ref exceptionBuffer, newExceptions, null);
                }

                lock (exceptionBuffer)
                    exceptionBuffer.Add(e);
            }

            if (tasks != null)
            {
                tasks.Pop();
            }

            using (executionLock.AcquireExclusiveUsing())
            {
                executing--;
                if (executing == 0)
                {
                    if (exceptionBuffer != null)
                    {
#if UNSHARPER
                        //workaround for volatile int to const int& casting problem in c++.
                        int val = runCount;
                        exceptions.Add(val, exceptionBuffer.ToArray());
#else
                        exceptions.Add(runCount, exceptionBuffer.ToArray());
#endif
                    }
                    // wait for all children to complete
                    foreach (var child in children)
                    {
                        child.Wait();
                    }

                    runCount++;

                    // open the reset event, so tasks waiting on this one can continue
                    resetEvent.Set();

                    // wait for waiting tasks to all exit
                    while (waitCount > 0)
                    {
                        ;
                    }

                    if (Callback == null && DataCallback == null)
                    {
                        Requeue();
                    }
                    else
                    {
                        // if we have a callback, then queue for execution
                        CompletionCallbacks.Add(this);
                    }

                    return(true);
                }
                return(false);
            }
        }
Exemple #2
0
        public bool DoWork(int expectedID)
        {
            using (executionLock.AcquireExclusiveUsing())
            {
                if (expectedID < runCount)
                {
                    return(true);
                }
                if (work == null)
                {
                    return(false);
                }
                if (executing == work.Options.MaximumThreads)
                {
                    return(false);
                }
                executing++;
            }

            // associate the current task with this thread, so that Task.CurrentTask gives the correct result
            Stack <Task> tasks = null;

            if (!runningTasks.TryGet(Thread.CurrentThread, out tasks))
            {
                tasks = new Stack <Task>();
                runningTasks.Add(Thread.CurrentThread, tasks);
            }
            tasks.Push(new Task(this));

            // execute the task
            try { work.DoWork(); }
            catch (Exception e)
            {
                if (exceptionBuffer == null)
                {
                    var newExceptions = new List <Exception>();
                    Interlocked.CompareExchange(ref exceptionBuffer, newExceptions, null);
                }

                lock (exceptionBuffer)
                    exceptionBuffer.Add(e);
            }

            if (tasks != null)
            {
                tasks.Pop();
            }

            using (executionLock.AcquireExclusiveUsing())
            {
                executing--;
                if (executing == 0)
                {
                    if (exceptionBuffer != null)
                    {
                        exceptions.Add(runCount, exceptionBuffer.ToArray());
                    }

                    // wait for all children to complete
                    foreach (var child in children)
                    {
                        child.Wait();
                    }

                    runCount++;

                    // open the reset event, so tasks waiting on this one can continue
                    resetEvent.Set();

                    // wait for waiting tasks to all exit
                    while (waitCount > 0)
                    {
                        ;
                    }

                    if (Callback == null)
                    {
                        Requeue();
                    }
                    else
                    {
                        // if we have a callback, then queue for execution
                        CompletionCallbacks.Enqueue(this);
                    }

                    return(true);
                }
                return(false);
            }
        }