Exemple #1
0
        private void Dispatch()
        {
            ListenerChannel    channel     = _channel;
            SessionIdleManager idleManager = _idleManager;

            _channel     = null;
            _idleManager = null;

            try
            {
                if (channel != null)
                {
                    ChannelHandler handler = new ChannelHandler(_listenerBinder.MessageVersion, channel.Binder, this, idleManager);

                    if (!channel.Binder.HasSession)
                    {
                        _channelDispatcher.Channels.Add(channel.Binder.Channel);
                    }

                    if (channel.Binder is DuplexChannelBinder)
                    {
                        DuplexChannelBinder duplexChannelBinder = channel.Binder as DuplexChannelBinder;
                        duplexChannelBinder.ChannelHandler      = handler;
                        duplexChannelBinder.DefaultCloseTimeout = this.DefaultCloseTimeout;

                        if (_timeouts == null)
                        {
                            duplexChannelBinder.DefaultSendTimeout = ServiceDefaults.SendTimeout;
                        }
                        else
                        {
                            duplexChannelBinder.DefaultSendTimeout = _timeouts.SendTimeout;
                        }
                    }

                    ChannelHandler.Register(handler);
                    channel     = null;
                    idleManager = null;
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                this.HandleError(e);
            }
            finally
            {
                if (channel != null)
                {
                    channel.Binder.Channel.Abort();
                    if (idleManager != null)
                    {
                        idleManager.CancelTimer();
                    }
                }
            }
        }
        bool TransactedAccept(out Transaction tx)
        {
            tx = null;

            try
            {
                tx = TransactionBehavior.CreateTransaction(this.ChannelDispatcher.TransactionIsolationLevel, this.ChannelDispatcher.TransactionTimeout);

                IChannelBinder binder = null;
                using (TransactionScope scope = new TransactionScope(tx))
                {
                    TimeSpan acceptTimeout = TimeoutHelper.Min(this.ChannelDispatcher.TransactionTimeout, this.ChannelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout);
                    if (!this.acceptor.TryAccept(TransactionBehavior.NormalizeTimeout(acceptTimeout), out binder))
                    {
                        return(false);
                    }
                    scope.Complete();
                }
                if (null != binder)
                {
                    this.channel     = new ListenerChannel(binder);
                    this.idleManager = SessionIdleManager.CreateIfNeeded(this.channel.Binder, this.channelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout);
                    return(true);
                }
                else
                {
                    this.AcceptedNull();
                    tx = null;
                    return(false);
                }
            }
            catch (CommunicationException e)
            {
                if (null != tx)
                {
                    try
                    {
                        tx.Rollback();
                    }
                    catch (TransactionException ex)
                    {
                        DiagnosticUtility.TraceHandledException(ex, TraceEventType.Information);
                    }
                }
                tx = null;

                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);

                return(false);
            }
            catch (TransactionException e)
            {
                tx = null;

                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);

                return(false);
            }
        }
Exemple #3
0
        private void CancelPendingIdleManager()
        {
            SessionIdleManager idleManager = _idleManager;

            if (idleManager != null)
            {
                idleManager.CancelTimer();
            }
        }
        bool HandleEndAccept(IAsyncResult result)
        {
            this.channel = this.CompleteAccept(result);

            if (this.channel != null)
            {
                Fx.Assert(this.idleManager == null, "There cannot be an existing idle manager");
                this.idleManager = SessionIdleManager.CreateIfNeeded(this.channel.Binder, this.channelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout);
            }
            else
            {
                this.DoneAccepting();
                return(true);
            }

            return(this.AcquireThrottle());
        }
Exemple #5
0
        private void OpenAndEnsurePump()
        {
            Exception exception = null;

            try
            {
                _binder.Channel.Open();
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                exception = e;
            }

            if (exception != null)
            {
                SessionIdleManager idleManager = _idleManager;
                if (idleManager != null)
                {
                    idleManager.CancelTimer();
                }

                bool errorHandled = this.HandleError(exception);

                if (_incrementedActivityCountInConstructor)
                {
                    _listener.ChannelDispatcher.Channels.DecrementActivityCount();
                }

                if (!errorHandled)
                {
                    _binder.Channel.Abort();
                }
            }
            else
            {
                this.EnsurePump();
            }
        }
Exemple #6
0
        internal ChannelHandler(MessageVersion messageVersion, IChannelBinder binder,
                                ListenerHandler listener, SessionIdleManager idleManager)
        {
            ChannelDispatcher channelDispatcher = listener.ChannelDispatcher;

            _messageVersion     = messageVersion;
            _isManualAddressing = channelDispatcher.ManualAddressing;
            _binder             = binder;
            _listener           = listener;

            _receiveSynchronously = channelDispatcher.ReceiveSynchronously;
            _sendAsynchronously   = channelDispatcher.SendAsynchronously;
            _duplexBinder         = binder as DuplexChannelBinder;
            _hasSession           = binder.HasSession;
            _isConcurrent         = ConcurrencyBehavior.IsConcurrent(channelDispatcher, _hasSession);

            if (channelDispatcher.MaxPendingReceives > 1)
            {
                throw NotImplemented.ByDesign;
            }

            if (channelDispatcher.BufferedReceiveEnabled)
            {
                _binder = new BufferedReceiveBinder(_binder);
            }

            _receiver    = new ErrorHandlingReceiver(_binder, channelDispatcher);
            _idleManager = idleManager;
            Fx.Assert((_idleManager != null) == (_binder.HasSession && _listener.ChannelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout != TimeSpan.MaxValue), "idle manager is present only when there is a session with a finite receive timeout");


            _requestInfo = new RequestInfo(this);

            if (_listener.State == CommunicationState.Opened)
            {
                _listener.ChannelDispatcher.Channels.IncrementActivityCount();
                _incrementedActivityCountInConstructor = true;
            }
        }
        internal ChannelHandler(MessageVersion messageVersion, IChannelBinder binder,
            ListenerHandler listener, SessionIdleManager idleManager)
        {
            ChannelDispatcher channelDispatcher = listener.ChannelDispatcher;

            _messageVersion = messageVersion;
            _isManualAddressing = channelDispatcher.ManualAddressing;
            _binder = binder;
            _listener = listener;

            _receiveSynchronously = channelDispatcher.ReceiveSynchronously;
            _sendAsynchronously = channelDispatcher.SendAsynchronously;
            _duplexBinder = binder as DuplexChannelBinder;
            _hasSession = binder.HasSession;
            _isConcurrent = ConcurrencyBehavior.IsConcurrent(channelDispatcher, _hasSession);

            if (channelDispatcher.MaxPendingReceives > 1)
            {
                throw NotImplemented.ByDesign;
            }

            if (channelDispatcher.BufferedReceiveEnabled)
            {
                _binder = new BufferedReceiveBinder(_binder);
            }

            _receiver = new ErrorHandlingReceiver(_binder, channelDispatcher);
            _idleManager = idleManager;
            Fx.Assert((_idleManager != null) == (_binder.HasSession && _listener.ChannelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout != TimeSpan.MaxValue), "idle manager is present only when there is a session with a finite receive timeout");

            _requestInfo = new RequestInfo(this);

            if (_listener.State == CommunicationState.Opened)
            {
                _listener.ChannelDispatcher.Channels.IncrementActivityCount();
                _incrementedActivityCountInConstructor = true;
            }
        }
        internal ChannelHandler(MessageVersion messageVersion, IChannelBinder binder, ServiceThrottle throttle,
            ListenerHandler listener, bool wasChannelThrottled, WrappedTransaction acceptTransaction, SessionIdleManager idleManager)
        {
            ChannelDispatcher channelDispatcher = listener.ChannelDispatcher;

            this.messageVersion = messageVersion;
            this.isManualAddressing = channelDispatcher.ManualAddressing;
            this.binder = binder;
            this.throttle = throttle;
            this.listener = listener;
            this.wasChannelThrottled = wasChannelThrottled;

            this.host = listener.Host;
            this.receiveSynchronously = channelDispatcher.ReceiveSynchronously;
            this.sendAsynchronously = channelDispatcher.SendAsynchronously;
            this.duplexBinder = binder as DuplexChannelBinder;
            this.hasSession = binder.HasSession;
            this.isConcurrent = ConcurrencyBehavior.IsConcurrent(channelDispatcher, this.hasSession);

            if (channelDispatcher.MaxPendingReceives > 1)
            {
                // We need to preserve order if the ChannelHandler is not concurrent.
                this.binder = new MultipleReceiveBinder(
                    this.binder,
                    channelDispatcher.MaxPendingReceives,
                    !this.isConcurrent);
            }

            if (channelDispatcher.BufferedReceiveEnabled)
            {
                this.binder = new BufferedReceiveBinder(this.binder);
            }

            this.receiver = new ErrorHandlingReceiver(this.binder, channelDispatcher);
            this.idleManager = idleManager;
            Fx.Assert((this.idleManager != null) == (this.binder.HasSession && this.listener.ChannelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout != TimeSpan.MaxValue), "idle manager is present only when there is a session with a finite receive timeout");

            if (channelDispatcher.IsTransactedReceive && !channelDispatcher.ReceiveContextEnabled)
            {
                receiveSynchronously = true;
                receiveWithTransaction = true;

                if (channelDispatcher.MaxTransactedBatchSize > 0)
                {
                    int maxConcurrentBatches = 1;
                    if (null != throttle && throttle.MaxConcurrentCalls > 1)
                    {
                        maxConcurrentBatches = throttle.MaxConcurrentCalls;
                        foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                        {
                            if (ConcurrencyMode.Multiple != endpointDispatcher.DispatchRuntime.ConcurrencyMode)
                            {
                                maxConcurrentBatches = 1;
                                break;
                            }
                        }
                    }

                    this.sharedTransactedBatchContext = new SharedTransactedBatchContext(this, channelDispatcher, maxConcurrentBatches);
                    this.isMainTransactedBatchHandler = true;
                    this.throttle = null;
                }
            }
            else if (channelDispatcher.IsTransactedReceive && channelDispatcher.ReceiveContextEnabled && channelDispatcher.MaxTransactedBatchSize > 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.IncompatibleBehaviors)));
            }

            if (this.binder.HasSession)
            {
                this.sessionOpenNotification = this.binder.Channel.GetProperty<SessionOpenNotification>();
                this.needToCreateSessionOpenNotificationMessage = this.sessionOpenNotification != null && this.sessionOpenNotification.IsEnabled;
            }

            this.acceptTransaction = acceptTransaction;
            this.requestInfo = new RequestInfo(this);

            if (this.listener.State == CommunicationState.Opened)
            {
                this.listener.ChannelDispatcher.Channels.IncrementActivityCount();
                this.incrementedActivityCountInConstructor = true;
            }
        }
        void Dispatch()
        {
            ListenerChannel    channel     = this.channel;
            SessionIdleManager idleManager = this.idleManager;

            this.channel     = null;
            this.idleManager = null;

            try
            {
                if (channel != null)
                {
                    ChannelHandler handler = new ChannelHandler(listenerBinder.MessageVersion, channel.Binder, this.throttle, this, (channel.Throttle != null), this.wrappedTransaction, idleManager);

                    if (!channel.Binder.HasSession)
                    {
                        this.channelDispatcher.Channels.Add(channel.Binder.Channel);
                    }

                    if (channel.Binder is DuplexChannelBinder)
                    {
                        DuplexChannelBinder duplexChannelBinder = channel.Binder as DuplexChannelBinder;
                        duplexChannelBinder.ChannelHandler      = handler;
                        duplexChannelBinder.DefaultCloseTimeout = this.DefaultCloseTimeout;

                        if (this.timeouts == null)
                        {
                            duplexChannelBinder.DefaultSendTimeout = ServiceDefaults.SendTimeout;
                        }
                        else
                        {
                            duplexChannelBinder.DefaultSendTimeout = timeouts.SendTimeout;
                        }
                    }

                    ChannelHandler.Register(handler);
                    channel     = null;
                    idleManager = null;
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                this.HandleError(e);
            }
            finally
            {
                if (channel != null)
                {
                    channel.Binder.Channel.Abort();
                    if (this.throttle != null && this.channelDispatcher.Session)
                    {
                        this.throttle.DeactivateChannel();
                    }
                    if (idleManager != null)
                    {
                        idleManager.CancelTimer();
                    }
                }
            }
        }
Exemple #10
0
        private void Dispatch()
        {
            ListenerChannel channel = _channel;
            SessionIdleManager idleManager = _idleManager;
            _channel = null;
            _idleManager = null;

            try
            {
                if (channel != null)
                {
                    ChannelHandler handler = new ChannelHandler(_listenerBinder.MessageVersion, channel.Binder, this, idleManager);

                    if (!channel.Binder.HasSession)
                    {
                        _channelDispatcher.Channels.Add(channel.Binder.Channel);
                    }

                    if (channel.Binder is DuplexChannelBinder)
                    {
                        DuplexChannelBinder duplexChannelBinder = channel.Binder as DuplexChannelBinder;
                        duplexChannelBinder.ChannelHandler = handler;
                        duplexChannelBinder.DefaultCloseTimeout = this.DefaultCloseTimeout;

                        if (_timeouts == null)
                            duplexChannelBinder.DefaultSendTimeout = ServiceDefaults.SendTimeout;
                        else
                            duplexChannelBinder.DefaultSendTimeout = _timeouts.SendTimeout;
                    }

                    ChannelHandler.Register(handler);
                    channel = null;
                    idleManager = null;
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                this.HandleError(e);
            }
            finally
            {
                if (channel != null)
                {
                    channel.Binder.Channel.Abort();
                    if (idleManager != null)
                    {
                        idleManager.CancelTimer();
                    }
                }
            }
        }
        void Dispatch()
        {
            ListenerChannel channel = this.channel;
            SessionIdleManager idleManager = this.idleManager;
            this.channel = null;
            this.idleManager = null;

            try
            {
                if (channel != null)
                {
                    ChannelHandler handler = new ChannelHandler(listenerBinder.MessageVersion, channel.Binder, this.throttle, this, (channel.Throttle != null), this.wrappedTransaction, idleManager);

                    if (!channel.Binder.HasSession)
                    {
                        this.channelDispatcher.Channels.Add(channel.Binder.Channel);
                    }

                    if (channel.Binder is DuplexChannelBinder)
                    {
                        DuplexChannelBinder duplexChannelBinder = channel.Binder as DuplexChannelBinder;
                        duplexChannelBinder.ChannelHandler = handler;
                        duplexChannelBinder.DefaultCloseTimeout = this.DefaultCloseTimeout;

                        if (this.timeouts == null)
                            duplexChannelBinder.DefaultSendTimeout = ServiceDefaults.SendTimeout;
                        else
                            duplexChannelBinder.DefaultSendTimeout = timeouts.SendTimeout;
                    }

                    ChannelHandler.Register(handler);
                    channel = null;
                    idleManager = null;
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                this.HandleError(e);
            }
            finally
            {
                if (channel != null)
                {
                    channel.Binder.Channel.Abort();
                    if (this.throttle != null && this.channelDispatcher.Session)
                    {
                        this.throttle.DeactivateChannel();
                    }
                    if (idleManager != null)
                    {
                        idleManager.CancelTimer();
                    }
                }
            }
        }
        bool HandleEndAccept(IAsyncResult result)
        {
            this.channel = this.CompleteAccept(result);

            if (this.channel != null)
            {
                Fx.Assert(this.idleManager == null, "There cannot be an existing idle manager");
                this.idleManager = SessionIdleManager.CreateIfNeeded(this.channel.Binder, this.channelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout);
            }
            else
            {
                this.DoneAccepting();
                return true;
            }

            return this.AcquireThrottle();
        }
        bool TransactedAccept(out Transaction tx)
        {
            tx = null;

            try
            {
                tx = TransactionBehavior.CreateTransaction(this.ChannelDispatcher.TransactionIsolationLevel, this.ChannelDispatcher.TransactionTimeout);

                IChannelBinder binder = null;
                using (TransactionScope scope = new TransactionScope(tx))
                {
                    TimeSpan acceptTimeout = TimeoutHelper.Min(this.ChannelDispatcher.TransactionTimeout, this.ChannelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout);
                    if (!this.acceptor.TryAccept(TransactionBehavior.NormalizeTimeout(acceptTimeout), out binder))
                    {
                        return false;
                    }
                    scope.Complete();
                }
                if (null != binder)
                {
                    this.channel = new ListenerChannel(binder);
                    this.idleManager = SessionIdleManager.CreateIfNeeded(this.channel.Binder, this.channelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout);
                    return true;
                }
                else
                {
                    this.AcceptedNull();
                    tx = null;
                    return false;
                }
            }
            catch (CommunicationException e)
            {
                if (null != tx)
                {
                    try
                    {
                        tx.Rollback();
                    }
                    catch (TransactionException ex)
                    {
                        DiagnosticUtility.TraceHandledException(ex, TraceEventType.Information);
                    }
                }
                tx = null;

                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);

                return false;
            }
            catch (TransactionException e)
            {
                tx = null;

                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);

                return false;
            }
        }