/// <summary> /// Executes a parametrized task with one of the free worker threads. /// </summary> /// <param name="task">The task you want to be executed.</param> /// <param name="parameters">The parameters of the task.</param> /// <remarks> /// This function returns immediately as soon as a free worker thread has been /// found and it has started to execute the given task. /// </remarks> public void ExecuteTask(ParametrizedWorkerTask task, object[] parameters) { /// wait until a new task can be added this.clientSemaphore.WaitOne(); /// send a signal that a new task is being added, so the WaitForCurrentTasks() /// function will block the caller from now. this.everyCurrentTaskCompletedEvent.Reset(); /// add the new task this.administrationMutex.WaitOne(); while (null != this.nonParamTaskList[this.nextTaskToCheck] || null != this.paramTaskList[this.nextTaskToCheck]) { this.nextTaskToCheck++; if (this.nextTaskToCheck == this.nonParamTaskList.Length) { this.nextTaskToCheck = 0; } } this.paramTaskList[this.nextTaskToCheck] = task; this.taskParameterList[this.nextTaskToCheck] = parameters; this.administrationMutex.Release(); /// release a worker thread this.workerSemaphore.Release(); }
/// <summary> /// Every worker thread starts executing this function. /// </summary> private void WorkerProc() { WaitHandle[] objectsToWait = new WaitHandle[] { this.workerSemaphore, this.terminateEvent }; /// execute this while until the this.terminateEvent is signaled while (1 != WaitHandle.WaitAny(objectsToWait)) { this.administrationMutex.WaitOne(); /// select a task to execute WorkerTask selectedWorkerTask = null; ParametrizedWorkerTask selectedParamTask = null; object[] selectedTaskParamList = null; while (null == this.nonParamTaskList[this.nextTaskToCheck] && null == this.paramTaskList[this.nextTaskToCheck]) { this.nextTaskToCheck++; if (this.nextTaskToCheck == this.nonParamTaskList.Length) { this.nextTaskToCheck = 0; } } selectedWorkerTask = this.nonParamTaskList[this.nextTaskToCheck]; selectedParamTask = this.paramTaskList[this.nextTaskToCheck]; selectedTaskParamList = this.taskParameterList[this.nextTaskToCheck]; this.nonParamTaskList[this.nextTaskToCheck] = null; this.paramTaskList[this.nextTaskToCheck] = null; this.taskParameterList[this.nextTaskToCheck] = null; this.administrationMutex.Release(); try { /// execute the selected task if (null != selectedWorkerTask) { /// a non-parametrized task has been found selectedWorkerTask(); } else { /// a parametrized task has been found selectedParamTask(selectedTaskParamList); } } catch (Exception e) { TraceManager.WriteExceptionAllTrace(e, false); lock (this.caughtExceptionList) { this.caughtExceptionList.Add(e); } } /// release a client if (this.clientSemaphore.Release() == this.nonParamTaskList.Length - 1) { /// send a signal if there is no more task currently waiting. this.everyCurrentTaskCompletedEvent.Set(); } } }