protected virtual ServiceMessageEventArgs CreateServiceMessageEventArgs(SSSBMessage message, CancellationToken cancellation) { ServiceMessageEventArgs args = new ServiceMessageEventArgs(message, this._sssbService, cancellation, _services.CreateScope()); return(args); }
private async Task <bool> _DispatchMessage(SqlConnection dbconnection, SSSBMessage message, CancellationToken token) { // возвратить ли сообщение назад в очередь? bool rollBack = false; IMessageHandler <ServiceMessageEventArgs> messageHandler; // if we registered custom handlers for predefined message types if (_messageHandlers.TryGetValue(message.MessageType, out messageHandler)) { ServiceMessageEventArgs serviceArgs = this.CreateServiceMessageEventArgs(message, token); try { bool isSync = true; Task processTask = Task.FromException(new Exception($"The message: {message.MessageType} ConversationHandle: {message.ConversationHandle} is not handled")); try { using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) { serviceArgs = await messageHandler.HandleMessage(this._sssbService, serviceArgs).ConfigureAwait(continueOnCapturedContext: false); transactionScope.Complete(); } isSync = serviceArgs.Completion.IsCompleted; } catch (Exception handleEx) { if (!serviceArgs.TaskCompletionSource.TrySetException(handleEx)) { _logger.LogError(ErrorHelper.GetFullMessage(handleEx)); } } finally { processTask = this._HandleProcessingResult(dbconnection, message, token, serviceArgs, isSync); } if (isSync) { await processTask; } } catch (Exception ex) { if (!serviceArgs.TaskCompletionSource.TrySetException(ex)) { _logger.LogError(ErrorHelper.GetFullMessage(ex)); } } } else if (message.MessageType == SSSBMessage.EndDialogMessageType) { await _standardMessageHandlers.EndDialogMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.ErrorMessageType) { await _standardMessageHandlers.ErrorMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.EchoMessageType && message.ContractName == EchoContractName) { await _standardMessageHandlers.EchoMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.PPS_EmptyMessageType) { await _standardMessageHandlers.EndDialogMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.PPS_StepCompleteMessageType) { //just awake from sleep } else { throw new Exception(string.Format(ServiceBrokerResources.UnknownMessageTypeErrMsg, message.MessageType)); } return(rollBack); }
Task _HandleProcessingResult(SqlConnection dbconnection, SSSBMessage message, CancellationToken token, ServiceMessageEventArgs serviceArgs, bool isSync) { Task processTask = serviceArgs.Completion.ContinueWith(async(antecedent) => { try { if (isSync) { await this.HandleSyncProcessingResult(dbconnection, message, token, antecedent); } else { await this.HandleAsyncProcessingResult(message, token, antecedent); } } catch (OperationCanceledException) { // NOOP } catch (PPSException) { // Already Logged } catch (Exception ex) { _logger.LogError(ErrorHelper.GetFullMessage(ex)); } }, isSync? TaskContinuationOptions.ExecuteSynchronously: TaskContinuationOptions.None).Unwrap(); var disposeTask = processTask.ContinueWith((antecedent) => { try { serviceArgs.Dispose(); } catch (Exception ex) { _logger.LogError(ErrorHelper.GetFullMessage(ex)); } }, TaskContinuationOptions.ExecuteSynchronously); return(processTask); }