示例#1
0
        /// <summary>
        /// Procedure represents the notification callback provided by the
        /// TaskProxy. This callback is invoked whenever a task the TaskProxy
        /// is waiting on has been serviced by the TaskPool. When all the tasks the
        /// proxy is waiting on have been serviced it will signal external clients
        /// using the condition variable reference passed from the client at
        /// TaskProxy construction.
        /// </summary>
        /// <param name="tceArg"></param>
        private void OnTPTaskComplete(TPTaskCompleteEventArgs tceArg)
        {
            lock (m_results.SyncRoot)
            {
                // Index results by TaskID
                m_results.Add(tceArg.TaskID, tceArg);
                m_nTasksPending--;

                if (m_nTasksPending == 0)
                {
                    // Indicate results are ready by changing state
                    m_status = enuTaskProxyStatus.ResultsReady;
                    // Signal to any waiting client
                    m_condition.Set();
                }
            }
        }
示例#2
0
 /// <summary>
 /// TaskPool subscribes to the TPTaskComplete event. When a TPTask
 /// thread is finished servicing a request, locate the
 /// subscription of the client that queued the request and
 /// notify them via the callback they provided as part of
 /// their subscription.
 /// <seealso cref="TPTask"/>
 /// <seealso cref="TPTaskCompleteEventArgs"/>
 /// </summary>
 /// <param name="tceArg">TPTask completion event arguement</param>
 private static void OnTPTaskComplete(TPTaskCompleteEventArgs tceArg)
 {
     try
     {
         lock (ClientNotification.SyncRoot)
         {
             if (ClientNotification.ContainsKey(tceArg.TaskID))
             {
                 TaskRequest.NotificationCallback objNotify = (TaskRequest.NotificationCallback)ClientNotification[tceArg.TaskID];
                 if (objNotify != null)
                 {
                     // Notifiy specific client
                     objNotify(tceArg);
                     // Remove subscription
                     ClientNotification.Remove(tceArg.TaskID);
                 }
             }
         }
     }
     catch (Exception /*e*/)
     {}
 }
        /// <summary>
        /// Procedure enforces the leader-followers behavior of TPTask threads
        /// </summary>
        /// <remarks></remarks>
        public void Service()
        {
            // Every thread that comes thru here ups the thread count
            Interlocked.Increment(ref nNumTasks);

            while (true)
            {
                // Begin critical section
                lock (this)
                {
                    Console.WriteLine("Checking for leader");
                    // While a leader has been selected...wait around
                    while (bLeaderAvailable)
                    {
                        Console.WriteLine("Waiting to be leader");
                        m_leaderSignal.WaitOnSignal();
                        Console.WriteLine("Received leader signal");
                    }

                    // Assert self as leader before leaving critical section
                    bLeaderAvailable = true;
                    // Leave critical section
                    Console.WriteLine("Leaving as leader");
                }

                // Only one thread active at this point

                Console.WriteLine("Waiting on work");

                // waiting on work
                m_workSignal.WaitOnSignal();

                Console.WriteLine("Got work");

                bool bExitLoop = false;

                // Nothing else to do so this thread can exit or be recycled
                if (requestQ.Count == 0)
                {
                    // No work to do so let other threads (next leader) wait on work
                    m_workSignal.Reset();
                    bExitLoop = true;
                }

                // Begin critical section
                lock (this)
                {
                    // Signal self is no longer the leader
                    bLeaderAvailable = false;

                    // Signal a follower to become the new leader
                    m_leaderSignal.Signal();
                    // Leave critical section
                }

                if (bExitLoop)
                {
                    // If this task is not marked as recyclable
                    // then it must exit if no requests are
                    // pending
                    if (!m_bRecycleTask)
                    {
                        // Thread on its way out so decrease thread count
                        Interlocked.Decrement(ref nNumTasks);
                        break;
                    }
                }
                else
                {
                    try
                    {
                        // Dequeue Service request
                        TaskRequest req = (TaskRequest)requestQ.Dequeue();
                        // Set taskID
                        this.TaskID = req.TaskID;
                        // Execute Callback
                        object objRes = req.TaskCb(req.Context);
                        // If any one subscribed, then fire LFTaskDone event
                        if (TPTaskComplete != null)
                        {
                            TPTaskCompleteEventArgs tceArg = new TPTaskCompleteEventArgs();
                            tceArg.TaskID = req.TaskID;
                            tceArg.Result = objRes;
                            TPTaskComplete(tceArg);
                        }
                    }
                    catch (Exception e)                     // Catch any exceptions thrown
                    {
                        // If any one subscribed, then fire LFTaskFailed event
                        if (TPTaskComplete != null)
                        {
                            TPTaskCompleteEventArgs tceArg = new TPTaskCompleteEventArgs();
                            tceArg.TaskID = this.TaskID;
                            // Signal that we had errors so that
                            // clients can check the
                            // ExceptionMessage property
                            tceArg.HasErrors = true;
                            tceArg.Result    = e.Message;
                            TPTaskComplete(tceArg);
                        }
                    }
                    finally
                    {
                        // Reset task ID
                        this.TaskID = Guid.Empty;
                    }
                }
            }    // End-while(true)
        }        // End-Method Service()