public void Run() { while (!mAbort) { IBuildTask task = null; lock (mSemaphore) { if (mTask != null && mTask.TaskState == BuildTaskState.Inactive) { task = mTask; mTask = null; } } if (task == null) { Thread.Sleep(100); } else { // Have to re-check. State may have changed. if (task.TaskState == BuildTaskState.Inactive) { /* * Design note: * * This is a trade-off to deal with poorly written tasks. Technically, * the task is responsible for catching and reporting its own * exceptions. But if it doesn't it can bring down the processor * thread. * * This method forces the task to abort so the main manager can detect * and discard it. But if the task is so poorly written that the * abort doesn't work, or throws another exception, then the processor * will become a zombie, unresponsive to new requests from the manager. */ try { task.Run(); } catch (Exception ex) { task.Abort("Exception detected by processor: " + ex.Message); } } } } }