in src/System.ServiceModel.Primitives/src/System/ServiceModel/Dispatcher/ImmutableDispatchRuntime.cs [760:937]
private void ProcessMessageCleanup(ref MessageRpc rpc)
{
Fx.Assert(
!object.ReferenceEquals(rpc.ErrorProcessor, _processMessageCleanupError),
"ProcessMessageCleanup run twice on the same MessageRpc!");
rpc.ErrorProcessor = _processMessageCleanupError;
bool replyWasSent = false;
if (rpc.CanSendReply)
{
if (_sendAsynchronously)
{
replyWasSent = EndReply(ref rpc);
}
else
{
replyWasSent = rpc.SuccessfullySendReply;
}
}
try
{
try
{
if (rpc.DidDeserializeRequestBody)
{
rpc.Request.Close();
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
_error.HandleError(e);
}
rpc.DisposeParameters(false); //Dispose all input/output/return parameters
if (rpc.FaultInfo.IsConsideredUnhandled)
{
if (!replyWasSent)
{
rpc.AbortRequestContext();
rpc.AbortChannel();
}
else
{
rpc.CloseRequestContext();
rpc.CloseChannel();
}
rpc.AbortInstanceContext();
}
else
{
if (rpc.RequestContextThrewOnReply)
{
rpc.AbortRequestContext();
}
else
{
rpc.CloseRequestContext();
}
}
if ((rpc.Reply != null) && (rpc.Reply != rpc.ReturnParameter))
{
try
{
rpc.Reply.Close();
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
_error.HandleError(e);
}
}
if ((rpc.FaultInfo.Fault != null) && (rpc.FaultInfo.Fault.State != MessageState.Closed))
{
// maybe ProvideFault gave a Message, but then BeforeSendReply replaced it
// in that case, we need to close the one from ProvideFault
try
{
rpc.FaultInfo.Fault.Close();
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
_error.HandleError(e);
}
}
try
{
rpc.OperationContext.FireOperationCompleted();
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
}
_instance.AfterReply(ref rpc, _error);
if (rpc.SuccessfullyLockedInstance)
{
try
{
_concurrency.UnlockInstance(ref rpc);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
Fx.Assert("Exceptions should be caught by callee");
rpc.InstanceContext.FaultInternal();
_error.HandleError(e);
}
}
if (_terminate != null)
{
try
{
_terminate.AfterReply(ref rpc);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
_error.HandleError(e);
}
}
if (rpc.SuccessfullyIncrementedActivity)
{
try
{
rpc.Channel.DecrementActivity();
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
_error.HandleError(e);
}
}
}
finally
{
if (rpc.Activity != null && DiagnosticUtility.ShouldUseActivity)
{
rpc.Activity.Stop();
}
}
_error.HandleError(ref rpc);
}