bool StartProcessing() { bool callAgain = false; SendOperation sendOperation = this.messageRpc.Operations[0]; this.currentClient = this.service.GetOrCreateClient <TContract>(sendOperation.CurrentEndpoint, this.messageRpc.Impersonating); if (TD.RoutingServiceTransmittingMessageIsEnabled()) { TD.RoutingServiceTransmittingMessage(this.messageRpc.EventTraceActivity, this.messageRpc.UniqueID, "0", this.currentClient.Key.ToString()); } try { if (messageRpc.Transaction != null && sendOperation.HasAlternate) { throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR.ErrorHandlingNotSupportedReqReplyTxn(this.messageRpc.OperationContext.Channel.LocalAddress))); } // We always work on cloned message when there are backup endpoints to handle exception cases Message message; if (sendOperation.AlternateEndpointCount > 0) { message = messageRpc.CreateBuffer().CreateMessage(); } else { message = messageRpc.Message; } sendOperation.PrepareMessage(message); IAsyncResult result = null; using (this.PrepareTransactionalCall(messageRpc.Transaction)) { IDisposable impersonationContext = null; try { //Perform the assignment in a finally block so it won't be interrupted asynchronously try { } finally { impersonationContext = messageRpc.PrepareCall(); } result = this.currentClient.BeginOperation(message, messageRpc.Transaction, this.PrepareAsyncCompletion(operationCallback), this); } finally { if (impersonationContext != null) { impersonationContext.Dispose(); } } } if (this.CheckSyncContinue(result)) { if (this.OperationComplete(result)) { this.Complete(this.allCompletedSync); } else { callAgain = true; } } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } if (!this.HandleClientOperationFailure(exception)) { throw; } callAgain = true; } return(callAgain); }
bool SendToCurrentClient() { MessageRpc messageRpc = this.service.SessionMessages[this.sessionMessageIndex]; SendOperation sendOperation = messageRpc.Operations[this.destinationIndex]; if (sendOperation.Sent) { this.MoveToNextClientOperation(messageRpc.Operations.Count); return(true); } else if (!this.channelExtension.ReceiveContextEnabled && this.channelExtension.TransactedReceiveEnabled && sendOperation.HasAlternate) { // We can't do error handling for oneway Transactional unless there's RC. throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR.ErrorHandlingNotSupportedTxNoRC(messageRpc.OperationContext.Channel.LocalAddress))); } RoutingEndpointTrait endpointTrait = sendOperation.CurrentEndpoint; this.client = this.service.GetOrCreateClient <TContract>(endpointTrait, messageRpc.Impersonating); try { // We always work on cloned message when there are backup endpoints to handle exception cases Message message; if (messageRpc.Operations.Count == 1 && sendOperation.AlternateEndpointCount == 0) { message = messageRpc.Message; } else { message = messageRpc.CreateBuffer().CreateMessage(); } sendOperation.PrepareMessage(message); IAsyncResult result; if (TD.RoutingServiceTransmittingMessageIsEnabled()) { TD.RoutingServiceTransmittingMessage(messageRpc.EventTraceActivity, messageRpc.UniqueID, this.destinationIndex.ToString(TD.Culture), this.client.Key.ToString()); } Transaction transaction = this.service.GetTransactionForSending(messageRpc); using (this.PrepareTransactionalCall(transaction)) { IDisposable impersonationContext = null; try { //Perform the assignment in a finally block so it won't be interrupted asynchronously try { } finally { impersonationContext = messageRpc.PrepareCall(); } result = this.client.BeginOperation(message, transaction, this.PrepareAsyncCompletion(clientOperationCallback), this); } finally { if (impersonationContext != null) { impersonationContext.Dispose(); } } } if (this.CheckSyncContinue(result)) { this.ClientOperationComplete(result); return(true); } else { return(false); } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } //See if we can handle this Exception... if (this.HandleClientOperationFailure(exception)) { return(true); } throw; } }