Ejemplo n.º 1
0
        /// <summary>
        /// Function adds to the list of TaskRequests a TaskProxy will
        /// wait on.
        /// </summary>
        /// <param name="req">The TaskRequest to wait on</param>
        /// <returns>The Guid (TaskID) associated with the request.
        /// This TaskID is used to query for results once the
        /// TaskProxy signals the client that all task requests have
        /// been serviced.</returns>
        /// <remarks>Note: The TaskRequest queued may or may not have set
        /// a notification callback, if one has been set the TaskProxy will
        /// REPLACE it with its own notification callback.</remarks>
        /// <exception cref="ArgumentNullException">Thrown if a null
        /// TaskRequest is added</exception>
        public Guid AddTaskRequest(TaskRequest req)
        {
            if (req == null)
            {
                throw new ArgumentNullException("TaskRequest is null");
            }

            // Assign taskID if we have to
            if (req.TaskID == Guid.Empty)
            {
                req.TaskID = Guid.NewGuid();
            }

            Guid taskID = req.TaskID;

            // Enqueue task
            lock (m_requestQ.SyncRoot)
            {
                if (m_status != enuTaskProxyStatus.AcceptingRequests)
                {
                    throw new InvalidOperationException("Proxy is no longer accepting requests - Check TaskProxy status");
                }

                // Link notify callback to TaskProxy
                // note use of = instead of +=
                // single TaskProxy is sole subscriber
                // to this request being serviced
                req.NotifyCb = new TaskRequest.NotificationCallback(this.OnTPTaskComplete);
                m_requestQ.Enqueue(req);
                m_nTasksPending++;
            }

            return(taskID);
        }
 public static void QueueTaskRequest(TaskRequest req)
 {
     lock (TPTask.requestQ.SyncRoot)
     {
         // Add request item to TPTask requestQ
         TPTask.requestQ.Enqueue(req);
     }
 }
        /// <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()
Ejemplo n.º 4
0
        /// <summary>
        /// Function queues a TaskRequest to the TaskPool
        /// </summary>
        /// <param name="req">The TaskRequest to queue</param>
        /// <returns>A Guid used as a TaskID - if the TaskPool is in the process of
        /// Shutting down then Guid.Empty is returned</returns>
        /// <exception cref="ArgumentNullException">Thrown if TaskRequest
        /// is null or not valid</exception>
        public static Guid QueueTask(TaskRequest req)
        {
            if (req == null || !req.IsValid)
            {
                throw new ArgumentNullException("TaskRequest is null or contains null valued callbacks");
            }

            // If taskpool is shutting down then return Guid.Empty
            if (bShuttingDown)
            {
                return(Guid.Empty);
            }

            if (!bInitialized)
            {
                Initialize();
            }

            Guid taskID = Guid.Empty;

            try
            {
                /*lock( TPTask.requestQ.SyncRoot )
                 * {
                 *      // Generate Guid - task id if none exists
                 *      if( req.TaskID == Guid.Empty )
                 *              req.TaskID = Guid.NewGuid();
                 *
                 *      taskID = req.TaskID;
                 *
                 *      // Add request item to TPTask requestQ
                 *      TPTask.requestQ.Enqueue( req );
                 * }// End-lock on TPTask.requestQ
                 */

                // Generate Guid - task id if none exists
                if (req.TaskID == Guid.Empty)
                {
                    req.TaskID = Guid.NewGuid();
                }

                taskID = req.TaskID;

                TPTask.QueueTaskRequest(req);

                TaskPool.workSignal.Signal();

                // Tag taskID to notification callback
                lock (ClientNotification.SyncRoot)
                {
                    if (taskID != Guid.Empty && req.NotifyCb != null)
                    {
                        ClientNotification.Add(taskID, req.NotifyCb);
                    }
                }                // End-lock on ClientNotification
            }
            catch (Exception /*e*/)
            {}

            // Return taskID to client
            return(taskID);
        }