public virtual AsyncTransmitterEndpoint GetEndpoint(IBaseMessage message) { // Provide a virtual "CreateEndpointParameters" method to map message to endpoint EndpointParameters endpointParameters = CreateEndpointParameters(message); lock (endpoints) { AsyncTransmitterEndpoint endpoint = (AsyncTransmitterEndpoint)endpoints[endpointParameters.SessionKey]; if (null == endpoint) { // we haven't seen this location so far this batch so make a new endpoint endpoint = (AsyncTransmitterEndpoint)Activator.CreateInstance(this.endpointType, new object[] { this }); if (null == endpoint) { throw new CreateEndpointFailed(this.endpointType.FullName, endpointParameters.OutboundLocation); } endpoint.Open(endpointParameters, this.HandlerPropertyBag, this.PropertyNamespace); if (endpoint.ReuseEndpoint) { endpoints[endpointParameters.SessionKey] = endpoint; } } return(endpoint); } }
protected virtual void Worker() { // Depending on the circumstances we might want to sort the messages form BizTalk into // sub-batches each of which would be processed independently. // If we sort into subbatches we will need a "Leave" for each otherwise do all the "Leaves" here // In this code we have only one batch. If a sort into subbatches was added this number might change. int BatchCount = 1; int MessageCount = this.messages.Count; int LeaveCount = MessageCount - BatchCount; for (int i = 0; i < LeaveCount; i++) { this.asyncTransmitter.Leave(); } bool needToLeave = true; try { using (Batch batch = new TransmitResponseBatch(this.transportProxy, new TransmitResponseBatch.AllWorkDoneDelegate(AllWorkDone))) { foreach (IBaseMessage message in this.messages) { AsyncTransmitterEndpoint endpoint = null; try { // Get appropriate endpoint for the message. Should always be non-null endpoint = (AsyncTransmitterEndpoint)asyncTransmitter.GetEndpoint(message); // ask the endpoint to process the message IBaseMessage responseMsg = endpoint.ProcessMessage(message); // success so tell the EPM we are finished with this message batch.DeleteMessage(message); if (responseMsg != null) { batch.SubmitResponseMessage(message, responseMsg); } //if we crash we could send duplicates - documentation point } catch (AdapterException e) { HandleException(e, batch, message); } catch (Exception e) { HandleException(new ErrorTransmitUnexpectedClrException(e.Message), batch, message); } finally { if (endpoint != null && endpoint.ReuseEndpoint == false) { endpoint.Dispose(); endpoint = null; } } } // If the Done call is successful then the callback will be called and Leave will be called there batch.Done(null); needToLeave = false; // Done didn't throw so no Need To Leave } } finally { // We need to Leave from this thread because the Done call failed and so there won't be any callback happening if (needToLeave) { this.asyncTransmitter.Leave(); } } }