/// <summary> /// Requests a cancellation of the output process. /// The cancellation is asynchronous and therefore the output process will need some time /// to finish with the state "Aborted". /// </summary> void IOutputProcess.Cancel() { lock (_syncLock) { if ((_currentState != OutputProcessState.Queued) && (_currentState != OutputProcessState.InProcess)) { return; } } var request = new TaskCancelRequestEnvelope() { TaskCancelRequest = new TaskCancelRequest() { Id = MessageId.Next, Destination = this.Destination, Source = this.Source } }; request.TaskCancelRequest.Task = new Types.Task[] { new Types.Task() { Id = this.Id.ToString(), Type = TaskType.Output } }; lock (_syncLock) { if ((_currentState == OutputProcessState.Queued) || (_currentState == OutputProcessState.InProcess)) { _currentState = OutputProcessState.Aborting; } } var response = (TaskCancelResponse)_messageDispatcher.SendAndWaitForResponse(request, request.TaskCancelRequest.Id, typeof(TaskCancelResponse)); if (response == null) { throw new ArgumentException("Waiting for the message 'TaskCancelResponse' failed."); } if ((response.Task == null) || (response.Task[0] == null)) { if (string.Compare(response.Task[0].Status, "CancelError", true) == 0) { throw new ApplicationException("Cancellation of output process failed."); } } }
/// <summary> /// Starts the output process by sending the according request to the storage system. /// </summary> void IOutputProcess.Start() { lock (_syncLock) { if (_currentState != OutputProcessState.Created) { return; } } var request = new OutputRequestEnvelope() { OutputRequest = this }; var outputMessageInterceptor = new MessageInterceptor(this.Id, typeof(OutputMessage)); _messageDispatcher.AddInterceptor(outputMessageInterceptor); var response = (OutputResponse)_messageDispatcher.SendAndWaitForResponse(request, this.Id, typeof(OutputResponse)); if (response == null) { _messageDispatcher.RemoveInterceptor(outputMessageInterceptor); outputMessageInterceptor.Dispose(); throw new ArgumentException("Waiting for the message 'OutputResponse' failed."); } if ((response.Details == null) || (Enum.TryParse <OutputProcessState>(response.Details.Status, out _currentState) == false)) { _currentState = OutputProcessState.Unknown; } if (_currentState != OutputProcessState.Queued) { if (_finished != null) { this.Trace("Raising event 'Finished'."); _finished(this, new EventArgs()); } } else { // wait for completion if (ThreadPool.QueueUserWorkItem(new WaitCallback(WaitForOutputMessage), outputMessageInterceptor) == false) { throw new ApplicationException("Starting observation thread failed."); } } }
/// <summary> /// Asynchronous thread which waits for the completion of the specified output message interceptor. /// </summary> /// <param name="messageInterceptor">The message interceptor to wait for.</param> private void WaitForOutputMessage(object messageInterceptor) { try { using (var interceptor = messageInterceptor as MessageInterceptor) { bool orderNotFinished = true; while (orderNotFinished) { interceptor.Wait(); var outputMessage = (OutputMessage)interceptor.Message; if (outputMessage != null) { lock (_syncLock) { if (outputMessage.Article != null) { foreach (var article in outputMessage.Article) { if (article.Pack != null) { foreach (var pack in article.Pack) { pack.ArticleId = TextConverter.UnescapeInvalidXmlChars(article.Id); } _dispensedPackList.AddRange(article.Pack); } } } if (outputMessage.Box != null) { foreach (var box in outputMessage.Box) { _boxList.Add(box.Number); } } if (Enum.TryParse <OutputProcessState>(outputMessage.Details.Status, out _currentState) == false) { _currentState = OutputProcessState.Unknown; } } } else { this.Error("Waiting for the message 'OutputMessage' failed."); lock (_syncLock) { _currentState = OutputProcessState.Unknown; } } if (_currentState.Equals(OutputProcessState.BoxReleased)) { if (_boxReleased != null) { lock (_syncLock) { this.Trace("Raising event 'Box Released'."); _boxReleased(this, new EventArgs()); _dispensedPackList.Clear(); } } } else { orderNotFinished = false; _messageDispatcher.RemoveInterceptor(interceptor); if (_finished != null) { this.Trace("Raising event 'Finished'."); _finished(this, new EventArgs()); } } } } } catch (Exception ex) { this.Error("Receiving and processing 'OutputMessage' failed!", ex); } }
/// <summary> /// Asynchronous thread which waits for the completion of the specified output message interceptor. /// </summary> /// <param name="messageInterceptor">The message interceptor to wait for.</param> private void WaitForOutputMessage(object messageInterceptor) { try { using (var interceptor = messageInterceptor as MessageInterceptor) { bool orderNotFinished = true; while (orderNotFinished) { interceptor.Wait(); var outputMessage = interceptor.Message as OutputMessage; if (outputMessage != null) { lock (_syncLock) { this._boxList.Clear(); this._dispensedPackList.Clear(); this._dispensedPackList.AddRange(outputMessage.GetPacks()); if (outputMessage.Box != null) { foreach (var box in outputMessage.Box) { _boxList.Add(box.Number); } } if (Enum.TryParse <OutputProcessState>(outputMessage.Details.Status, out _currentState) == false) { _currentState = OutputProcessState.Unknown; } } } else { this.Error("Waiting for the message 'OutputMessage' failed."); lock (_syncLock) { _currentState = OutputProcessState.Unknown; } } if (_currentState.Equals(OutputProcessState.BoxReleased)) { if (_boxReleased != null) { lock (_syncLock) { this.Trace("Raising event 'Box Released'."); _boxReleased(this, new EventArgs()); } } } else if (_currentState.Equals(OutputProcessState.Completed) || _currentState.Equals(OutputProcessState.Incomplete) || _currentState.Equals(OutputProcessState.Aborted)) { orderNotFinished = false; _messageDispatcher.RemoveInterceptor(interceptor); if (_finished != null) { this.Trace("Raising event 'Finished'."); _finished(this, new EventArgs()); } } else { continue; } } } } catch (Exception ex) { this.Error("Receiving and processing 'OutputMessage' failed!", ex); } }