当前位置:  开发笔记 > 编程语言 > 正文

如何正确使用.NET2.0串口.BaseStream进行异步操作

如何解决《如何正确使用.NET2.0串口.BaseStream进行异步操作》经验,为你挑选了1个好方法。

我试图使用.NET2.0 SerialPort的.BaseStream属性来进行异步读写(BeginWrite/EndWrite,BeginRead/EndRead).

我在这方面取得了一些成功,但过了一段时间后,我注意到(使用Process Explorer)应用程序正在使用的句柄逐渐增加,偶尔会增加一个额外的线程,这也增加了句柄数.

每次出现新线程时,上下文切换速率也会增加.

应用程序不断向PLC设备发送3个字节,并返回800个左右的字节,并以波特率57600进行.

最初的CSwitch Delta(再次来自Process Explorer)大约是2500,无论如何它似乎都很高.每次出现新线程时,此值都会增加,CPU负载也会相应增加.

我希望有人可能做过类似的事情,可以帮助我,甚至说'以上帝的名义,不要这样做.'

在下面的代码中,'this._stream'是从SerialPort.BaseStream获得的,而CommsResponse是我用作IAsyncresult状态对象的类.

这个代码对于我作为替代使用串口的TCP连接是常见的(我有一个CommsChannel基类,从它派生的串行和TCP通道)并且它没有这些问题所以我有理由充满希望CommsResponse类没有任何问题.

感激地收到任何评论.

    /// 
    /// Write byte data to the channel.
    /// 
    /// The byte array to write.
    private void Write(byte[] bytes)
    {
        try
        {
            // Write the data to the port asynchronously.
            this._stream.BeginWrite(bytes, 0, bytes.Length, new AsyncCallback(this.WriteCallback), null);
        }
        catch (IOException ex)
        {
            // Do stuff.
        }
        catch (ObjectDisposedException ex)
        {
            // Do stuff.
        }
    }

    /// 
    /// Asynchronous write callback operation.
    /// 
    private void WriteCallback(IAsyncResult ar)
    {
        bool writeSuccess = false;

        try
        {
            this._stream.EndWrite(ar);
            writeSuccess = true;
        }
        catch (IOException ex)
        {
            // Do stuff.
        }

        // If the write operation completed sucessfully, start the read process.
        if (writeSuccess) { this.Read(); }
    }

    /// 
    /// Read byte data from the channel.
    /// 
    private void Read()
    {
        try
        {
            // Create new comms response state object.
            CommsResponse response = new CommsResponse();

            // Begin the asynchronous read process to get response.
            this._stream.BeginRead(this._readBuffer, 0, this._readBuffer.Length, new AsyncCallback(this.ReadCallback), response);
        }
        catch (IOException ex)
        {
            // Do stuff.
        }
        catch (ObjectDisposedException ex)
        {
            // Do stuff.
        }
    }

    /// 
    /// Asynchronous read callback operation.
    /// 
    private void ReadCallback(IAsyncResult ar)
    {
        // Retrieve the comms response object.
        CommsResponse response = (CommsResponse)ar.AsyncState;

        try
        {
            // Call EndRead to complete call made by BeginRead.
            // At this point, new data will be in this._readbuffer.
            int numBytesRead = this._stream.EndRead(ar);

            if (numBytesRead > 0)
            {
                // Create byte array to hold newly received bytes.
                byte[] rcvdBytes = new byte[numBytesRead];

                // Copy received bytes from read buffer to temp byte array
                Buffer.BlockCopy(this._readBuffer, 0, rcvdBytes, 0, numBytesRead);

                // Append received bytes to the response data byte list.
                response.AppendBytes(rcvdBytes);

                // Check received bytes for a correct response.
                CheckResult result = response.CheckBytes();

                switch (result)
                {
                    case CheckResult.Incomplete: // Correct response not yet received.
                        if (!this._cancelComm)
                        {
                            this._stream.BeginRead(this._readBuffer, 0, this._readBuffer.Length,
                                new AsyncCallback(this.ReadCallback), response);
                        }
                        break;

                    case CheckResult.Correct:  // Raise event if complete response received.
                        this.OnCommResponseEvent(response);
                        break;

                    case CheckResult.Invalid: // Incorrect response
                        // Do stuff.
                        break;

                    default: // Unknown response
                        // Do stuff.
                        break;
                }
            }
            else
            {
                // Do stuff.
            }
        }
        catch (IOException ex)
        {
            // Do stuff.
        }
        catch (ObjectDisposedException ex)
        {
            // Do stuff.
        }
    }

kgiannakakis.. 5

一些建议:

由于您只发送3个字节,因此可以进行同步写操作.延迟不会是一个问题.

也不要一直创建新的AsyncCallback.创建一个Read和一个Write AsyncCallback,并在每个begin call中使用它.



1> kgiannakakis..:

一些建议:

由于您只发送3个字节,因此可以进行同步写操作.延迟不会是一个问题.

也不要一直创建新的AsyncCallback.创建一个Read和一个Write AsyncCallback,并在每个begin call中使用它.

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有