串行转并行

命令的传输形式有两种:

串行,并行

串行是指一条命令发送下去,得到了应答才继续发送下一条。

并行是指有几条命令,不管有没有收到应答,一律转下去,处理器把所有的命令存储起来,然后一条条处理。

串行的缺点是用户等待时间长,

并行则可能导致某些命令会被丢掉,但用户的命令很快就发送到处理器了。

 

所以串行的命令发送器做法就是:

有一个发送队列,有两个线程,一个接收线程,一个发送线程,一个事件。

发送一条命令,把事件waitone,阻塞,当接收线程接到回应或者超时了就Set一下事件,继续发送下一条。

 

并行的做法是去掉事件,只有发送队列里面有命令,就全部发送出去。

 

接收处理器

一个事件,三个线程,一个接收线程,一个发送线程,一个处理线程。

首先从接收队列里面取数据,如果取到数据,就委托给处理线程,这时候阻塞,处理完毕后调用发送线程发送处理的结果给命令发送器。继续从接收器处理下一条指令。

 

以下是设计的一个通讯器的发送和接收部分。

private void ContinuousReceive()
        {
            try
            {
                while (!m_cancellationTokenSource.IsCancellationRequested)
                {
                    int receivedBytes = m_socket.Receive(m_buffer);
                    if (receivedBytes > 0)
                    {
                        byte[] receive = new byte[receivedBytes];
                        Buffer.BlockCopy(m_buffer, 0, receive, 0, receivedBytes);
                        CommunicateData receiveData = new CommunicateData(receive);
                        m_lastReceivedDataTime = DateTime.Now;


                        m_onReceivedata(this, receiveData);
                        if (m_needSaveData)
                        {
                            m_receiveCollection.Add(receiveData);
                        }
                    }
                    else
                    {
                        Stop();
                        //Thread.Sleep(TimeSpan.FromSeconds(10));
                        Logger.Write(new LogEntry
                        {
                            Severity = System.Diagnostics.TraceEventType.Error,
                            Message = LogMessage.Message("Socket Receive 0 Bytes"),
                            Categories = new String[] { "Exception" }
                        });
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Write(new LogEntry
                {
                    Severity = System.Diagnostics.TraceEventType.Error,
                    Message = LogMessage.Message(e),
                    Categories = new String[] { "Exception" }
                });

                lock (m_exceptionDeal)
                {
                    if (!m_hasDealException)
                    {
                        Stop();
                        m_hasDealException = true;
                        m_onException(this, e);
                    }
                }
            }
        }
private void ContinuousSend()
        {
            try
            {
                while (!m_cancellationTokenSource.IsCancellationRequested)
                {
                    CommunicateData sendData;
                    if (!m_isDsp)
                    {
                        sendData = m_sendCollection.Take(m_cancellationTokenSource.Token);
                    }
                    else
                    {
                        sendData = m_sendCollectionPr.Take();
                    }

                    //if (m_needAdjustCommunicatorId)
                    //{
                    //    LastSendCommunicateData = sendData;
                    //}

                    m_onSendData(this, sendData);
                    m_socket.Send(sendData.Data);
                    if (m_onMccTimeout != null)
                    {
                        m_onMccTimeout();
                    }

                    if (SendIntervalSecond != 0)
                    {
                        Thread.Sleep(TimeSpan.FromSeconds(SendIntervalSecond));
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Write(new LogEntry
                {
                    Severity = System.Diagnostics.TraceEventType.Error,
                    Message = LogMessage.Message(e),
                    Categories = new String[] { "Exception" }
                });

                lock (m_exceptionDeal)
                {
                    if (!m_hasDealException)
                    {
                        Stop();
                        m_hasDealException = true;
                        m_onException(this, e);
                    }
                }
            }
        }
View Code

 

 

一些改进,比如某条命令需要插队,优先处理,那么就在处理的接受队列里面实现插队功能。

这个设计完全不考虑命令是什么形式的,各种业务需要根据自己的业务逻辑去实现一个命令的接口。

由于是有串转并,发送方有可能同时发几个命令,在接收方当成一个命令来处理,这就需要接收方根据命令的特征进行分包处理。

posted @ 2014-04-01 11:48  Diablo_hunter  阅读(1759)  评论(0编辑  收藏  举报