我试图使用.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中使用它.
一些建议:
由于您只发送3个字节,因此可以进行同步写操作.延迟不会是一个问题.
也不要一直创建新的AsyncCallback.创建一个Read和一个Write AsyncCallback,并在每个begin call中使用它.