File: System\ServiceModel\Dispatcher\TerminatingOperationBehavior.cs
Project: ndp\cdf\src\WCF\ServiceModel\System.ServiceModel.csproj (System.ServiceModel)
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
 
namespace System.ServiceModel.Dispatcher
{
    using System.Runtime;
    using System.ServiceModel.Channels;
 
    class TerminatingOperationBehavior
    {
        static void AbortChannel(object state)
        {
            ((IChannel)state).Abort();
        }
 
        public static TerminatingOperationBehavior CreateIfNecessary(DispatchRuntime dispatch)
        {
            if (IsTerminatingOperationBehaviorNeeded(dispatch))
            {
                return new TerminatingOperationBehavior();
            }
            else
            {
                return null;
            }
        }
 
        static bool IsTerminatingOperationBehaviorNeeded(DispatchRuntime dispatch)
        {
            for (int i = 0; i < dispatch.Operations.Count; i++)
            {
                DispatchOperation operation = dispatch.Operations[i];
 
                if (operation.IsTerminating)
                {
                    return true;
                }
            }
 
            return false;
        }
 
        internal void AfterReply(ref MessageRpc rpc)
        {
            if (rpc.Operation.IsTerminating && rpc.Channel.HasSession)
            {
                IOThreadTimer timer = new IOThreadTimer(new Action<object>(TerminatingOperationBehavior.AbortChannel),
                                                        rpc.Channel.Binder.Channel, false);
 
                timer.Set(rpc.Channel.CloseTimeout);
            }
        }
 
        internal static void AfterReply(ref ProxyRpc rpc)
        {
            if (rpc.Operation.IsTerminating && rpc.Channel.HasSession)
            {
                IChannel sessionChannel = rpc.Channel.Binder.Channel;
                rpc.Channel.Close(rpc.TimeoutHelper.RemainingTime());
            }
        }
    }
}