/// <summary> /// Documents the special transition. /// </summary> /// <param name="eventId">The event unique identifier.</param> /// <param name="exitRequest">The exit request.</param> /// <param name="removeEvent">if set to <c>true</c> [remove event].</param> /// <param name="autoResume">if set to <c>true</c> [automatic resume].</param> /// <param name="queueDataAccess">The queue data access.</param> /// <param name="executionTime">The execution time.</param> /// <returns></returns> private AsyncHandlerResult DoSpecialTransition(Guid eventId, AsyncHandlerEarlyExitRequest exitRequest, bool removeEvent, bool autoResume, IQueueDataAccess queueDataAccess, double executionTime) { AsyncHandlerResult result = null; switch (exitRequest) { case AsyncHandlerEarlyExitRequest.Pause: { DateTime nextOccurrence = DateTime.MinValue; // 默认当做是作业干预的延迟操作,沿用延迟时间 if (autoResume) { // 自动重启,设为1分钟后可调度 nextOccurrence = DateTime.Now.AddMinutes(1.0); } var newEventState = new AsyncEventState { EventId = eventId, NewState = 1, NewStatus = 10, NextOccurrence = nextOccurrence, RetryOperation = false, CurrentRetryCount = 0, ErrorCode = 0, ClearData = false, ExecutionTime = executionTime }; queueDataAccess.UpdateStateAndStatus(newEventState); result = new AsyncPausedResult(); break; } case AsyncHandlerEarlyExitRequest.Cancel: { var newEventState2 = new AsyncEventState { EventId = eventId, NewState = 3, NewStatus = 32, NextOccurrence = System.DateTime.MinValue, RetryOperation = false, CurrentRetryCount = 0, ErrorCode = 0, ClearData = false, ExecutionTime = executionTime }; queueDataAccess.UpdateStateAndStatus(newEventState2); result = new AsyncCanceledResult(); break; } default: AsyncServiceException.Assert(false, "错误的状态: " + exitRequest.ToString()); break; } if (removeEvent) { RemoveSpecialTransition(eventId); } return result; }
/// <summary> /// Processes the asynchronous event. /// </summary> /// <param name="eventData">The event data.</param> /// <returns></returns> public AsyncHandlerResult ProcessAsyncEvent(AsyncEvent eventData) { AsyncServiceException.Assert(eventData != null, "异步服务池处理器只能处理异步事件。"); if (_queueManager.ShuttingDown) { _queueManager.TrackCompleteOutstandingOperation(eventData, null, false); return null; } MyTrace.Write(TraceCategory.AsyncService, TraceLevel.Info, "正在处理异步作业。Id: {0} 作业类型: {1}", eventData.EventId, eventData.OperationType); var result = _queueManager.HandleSpecialTransition(eventData); if (result != null) { _queueManager.TrackCompleteOutstandingOperation(eventData, result, false); } else { SemaphoreSlim semaphoreSlim = null; bool hasDone = false; if ( _queueManager.Configuration.OperationTypeThrottle.TryGetValue(eventData.OperationType, out semaphoreSlim) && !semaphoreSlim.Wait(0)) { var failure = new AsyncFailedResult(new AsyncServiceException("服务正忙且请求未被完成,请稍后重试。")) { FriendlyMessage = "服务正忙且请求未被完成,请稍后重试。" }; result = new AsyncRetryResult(failure); hasDone = true; } if (!hasDone) _queueManager.TrackBeginExecutingOperation(eventData); if (_queueManager.ShuttingDown) { _queueManager.TrackCompleteOutstandingOperation(eventData, result, false); return result; } try { if (!hasDone) result = _handler(eventData); } catch (Exception ex) { ErrorAction action = _errorHandler.Handle(ex); AsyncServiceException.Assert(action != null, "错误处理后的动作不应为null。"); string errorFormat = action.ErrorMessage == null ? string.Empty : action.ErrorMessage; result = new AsyncFailedResult(ex, action.ErrorCode, errorFormat); switch (action.Type) { case ErrorActionType.Retry: result = new AsyncRetryResult((AsyncFailedResult) result); break; case ErrorActionType.Fail: break; case ErrorActionType.Suspend: if (action.ErrorCode == -2147204743) { result = new AsyncPausedResult(DateTime.Now.AddMinutes(0)); break; } else { result = new AsyncSystemPausedResult(action.ErrorCode, "{0}", action.ErrorMessage); break; } default: result = new AsyncSystemPausedResult(ex); throw; } } finally { EndAsynchronousEventProcessing(eventData, result); } } return result; }