private void FinalizeRequest() { lock (mMessages) { if (mState == BuildTaskState.Aborting) { // Don't care if the task actually finished. // An abort takes presidence. mState = BuildTaskState.Aborted; mData = default(T); } else { try { mState = GetResult(out mData) ? BuildTaskState.Complete : BuildTaskState.Aborted; } catch (System.Exception ex) { FinalizeRequest(ex); } } mIsFinished = true; // Always last. } }
/// <summary> /// Runs the task through to a finished state. /// </summary> /// <remarks> /// <para> /// Never call this method more than once. /// </para> /// <para> /// If <see cref="IsThreadSafe"/> is true, this method can be run on a separate /// thread from the object(s) that are monitoring the task state. /// </para> /// </remarks> public void Run() { lock (mMessages) { if (mState != BuildTaskState.Inactive) { return; } mState = BuildTaskState.InProgress; } try { while (LocalUpdate()) { lock (mMessages) { if (mState == BuildTaskState.Aborting) { break; } } } FinalizeRequest(); } catch (System.Exception ex) { FinalizeRequest(ex); } finally { FinalizeTask(); } }
private void FinalizeRequest(System.Exception ex) { lock (mMessages) { mMessages.Add(string.Format("Build task aborted on exception: {0} ({1})" , ex.Message, this.GetType().Name)); mData = default(T); mState = BuildTaskState.Aborted; mIsFinished = true; } }
/// <summary> /// Requests an abort of the task. /// </summary> /// <remarks> /// <para> /// There may be a delay in the actual abort for tasks running on a separate thread. /// </para> /// </remarks> /// <param name="reason">The reason for the abort.</param> public void Abort(string reason) { lock (mMessages) { if (mIsFinished) { return; } AddMessage(reason); if (mState == BuildTaskState.Inactive) { mState = BuildTaskState.Aborting; FinalizeRequest(); } else { mState = BuildTaskState.Aborting; } } }