/// <summary> /// Starts the manager/workers execution. /// If the execution has been started it has no effect. /// </summary> /// <param name="managerData">The data to be used by the manager thread during its execution</param> public void Start(TManagerData managerData) { Monitor.Enter(oLock); if (running) { Monitor.PulseAll(oLock); Monitor.Exit(oLock); return; } this.running = true; this.abortRequested = false; this.cancelRequested = false; this.SetupLists(); this.workFinished.Reset(); this.lastExecutionStatus = MWExecutionStatus.ExecutionInProgress; this.lastExecutionResult = default(TManagerResult); this.managerThread = new Thread(managerThreadTask); this.managerThread.IsBackground = this.runInBackground; this.managerThread.Start(managerData); Monitor.PulseAll(oLock); Monitor.Exit(oLock); }
/// <summary> /// Initializes a new instance of ManagerWorkers class /// </summary> /// <param name="numWorkers">Number of workers to use</param> public ManagerWorkers(int numWorkers) { this.abortRequested = true; this.NumWorkers = numWorkers; this.running = false; this.runInBackground = true; this.abortRequested = false; this.oLock = new Object(); this.workersLock = new ReaderWriterLock(); this.allWorkersFree = new ManualResetEvent(true); this.availiableWorker = new ManualResetEvent(true); this.workFinished = new ManualResetEvent(false); this.managerThreadTask = new ParameterizedThreadStart(this.ManagerThreadTask); this.lastExecutionStatus = MWExecutionStatus.Unknown; this.lastExecutionResult = default(TManagerResult); }
/// <summary> /// Performs the manager task by calling the ManagerTask method. /// When it completes, enqueues the worker in the Owner.idleWorkers queue. /// </summary> /// <param name="o">Object that contains the task data to be used by the manager thread</param> private void ManagerThreadTask(object o) { TManagerResult executionResult; if (!(o is TManagerData)) { OnExecutionAborted(); return; } try { OnExecutionStarted(); executionResult = ManagerTask((TManagerData)o); if (cancelRequested) { this.lastExecutionStatus = MWExecutionStatus.ExecutionCanceled; } else { this.lastExecutionStatus = MWExecutionStatus.ExecutionCompleted; } OnExecutionCompleted(); } catch (ThreadAbortException) { // Rise the ExecutionAborted event and ensure the finally block will be executed this.OnExecutionAborted(); this.lastExecutionResult = default(TManagerResult); this.lastExecutionStatus = MWExecutionStatus.ExecutionAborted; } finally { this.workersLock.AcquireWriterLock(-1); Thread.BeginCriticalRegion(); this.idleWorkers.Clear(); this.busyWorkers.Clear(); this.availiableWorker.Set(); this.allWorkersFree.Set(); this.workersLock.ReleaseWriterLock(); Thread.EndCriticalRegion(); this.workFinished.Set(); this.running = false; } }