示例#1
0
        // Run on its own thread, and invokes user code from it (task continuations)
        private void WriteFramesLoop()
        {
            if (LogAdapter.ExtendedLogEnabled)
            {
                LogAdapter.LogDebug("ConnectionIO", "WriteFramesLoop starting");
            }

            CommandToSend cmdToSend = null;

            try
            {
                var token = _threadCancelToken;

                while (!token.IsCancellationRequested)
                {
                    _commandOutboxEvent.WaitOne(1000);                     // maybe it's better to _cancellationToken.Register(action) ?

                    while (_commandOutbox.TryDequeue(out cmdToSend))
                    {
                        _waitingServerReply.Wait(token);                         // Contention sadly required by the server/amqp

                        // The command will signal that we can send more commands...
                        cmdToSend.Prepare(cmdToSend.ExpectsReply ? _waitingServerReply : null);

                        if (cmdToSend.ExpectsReply)                         // enqueues as awaiting a reply from the server
                        {
                            _waitingServerReply.Reset();                    // cannot send anything else

                            var queue = cmdToSend.Channel == 0
                                                                ? _awaitingReplyQueue :
                                        _conn.ResolveChannel(cmdToSend.Channel)._awaitingReplyQueue;

                            queue.Enqueue(cmdToSend);
                        }

                        // writes to socket
                        var frameWriter = cmdToSend.OptionalArg as IFrameContentWriter;
                        if (frameWriter != null)
                        {
                            frameWriter.Write(_amqpWriter, cmdToSend.Channel, cmdToSend.ClassId, cmdToSend.MethodId, cmdToSend.OptionalArg);
                        }
                        else
                        {
                            cmdToSend.commandGenerator(_amqpWriter, cmdToSend.Channel, cmdToSend.ClassId, cmdToSend.MethodId, cmdToSend.OptionalArg);
                        }

                        // if writing to socket is enough, set as complete
                        if (!cmdToSend.ExpectsReply)
                        {
                            cmdToSend.RunReplyAction(0, 0, null).IntentionallyNotAwaited();
                        }
                    }
                }

                LogAdapter.LogError("ConnectionIO", "WriteFramesLoop exiting");
            }
            catch (ThreadAbortException)
            {
                // no-op
            }
            catch (Exception ex)
            {
                LogAdapter.LogError("ConnectionIO", "WriteFramesLoop error. Last command " + cmdToSend.ToDebugInfo(), ex);

                this.InitiateAbruptClose(ex);
            }
        }
示例#2
0
        // Run on its own thread, and invokes user code from it (task continuations)
        private void WriteFramesLoop()
        {
            if (LogAdapter.IsDebugEnabled)
            {
                LogAdapter.LogDebug(LogSource, "WriteFramesLoop starting");
            }

            CommandToSend cmdToSend = null;

            _writeThreadRunning = true;

            try
            {
                var token = _threadCancelToken;

                while (!token.IsCancellationRequested)
                {
                    _commandOutboxEvent.WaitOne(1000);                     // maybe it's better to _cancellationToken.Register(action) ?

                    if (token.IsCancellationRequested)
                    {
                        break;                                                    // perf hit?
                    }
                    while (_commandOutbox.TryDequeue(out cmdToSend))
                    {
                        FlushCommand(cmdToSend);
                    }
                }

                if (LogAdapter.IsErrorEnabled)
                {
                    LogAdapter.LogError(LogSource, "WriteFramesLoop exiting");
                }
            }
            catch (ThreadAbortException)
            {
                // no-op
            }
            catch (Exception ex)
            {
                if (LogAdapter.IsErrorEnabled)
                {
                    LogAdapter.LogError(LogSource, "WriteFramesLoop error. Last command " + cmdToSend.ToDebugInfo(), ex);
                }

                this.InitiateAbruptClose(ex).IntentionallyNotAwaited();
            }
            finally
            {
                _writeThreadRunning = false;

                TryTriggerClean();
            }
        }