我正在使用Win32 API(重叠IO)进行串行端口通信。我使用PInvoke从我的C#代码调用Win32 API。
在我之前的实现中,接收器线程使用轮询机制读取数据(无限循环周期性地读取RX缓冲区)。现在,我正在尝试使用事件驱动方法来读取数据(使用WaitCommEvent API调用)。我们期望新的实现将降低CPU使用率并加快通信速度。
但是,在更改为事件驱动方法之后,与轮询机制相比,通信实际上变慢了,花费了两倍的时间来读取。
任何人都可以建议哪一种是最好的方法来提高通信速度并降低CPU使用率?
以下是我的代码段:
private void ReadDataForWindows()
{
var data = new byte[255];
// Specify a set of events to be monitored for the port.
if (SetCommMask(this.Handle, EV_DEFAULT))
{
while (this.Handle != (IntPtr)INVALID_HANDLE_VALUE)
{
uint eventMask = 0;
// Wait for an event to occur for the port.
eventMask = this.WaitForEvent();
if (eventMask == EV_RXCHAR)
{
this.ReadFromRXBuffer(data);
}
else if (eventMask == EV_ERR)
{
uint errors;
ClearCommError(this.Handle, out errors, IntPtr.Zero);
}
// Re-specify the set of events to be monitored for the port.
if (!SetCommMask(this.Handle, EV_DEFAULT))
{
break;
}
}
}
}
private void ReadFromRXBuffer(byte[] data)
{
uint dwBytesTransferred;
// Loop for waiting for the data.
do
{
// Read the data from the serial port.
this.Read(data, 255, out dwBytesTransferred);
// Display the data read.
if (dwBytesTransferred > 0)
{
if (this.DataReceived != null)
{
var dataReceived = new byte[dwBytesTransferred];
for (var i = 0; i < dwBytesTransferred; i++)
{
dataReceived[i] = data[i];
}
this.DataReceived(this, new ByteDataReceivedEventArgs(dataReceived, Convert.ToInt32(dwBytesTransferred)));
}
}
} while (dwBytesTransferred > 0);
}
private uint WaitForEvent()
{
uint eventMask = 0;
IntPtr evPtr = Marshal.AllocHGlobal(Marshal.SizeOf(eventMask));
Marshal.WriteInt32(evPtr, 0);
if (WaitCommEvent(this.Handle, evPtr, this.RxOvr.MemPtr) == false)
{
int error = Marshal.GetLastWin32Error();
// Operation is executing in the background
if (error == ERROR_IO_PENDING)
{
this.ReceiveSignal.WaitOne();
}
else
{
this.Fault = "WaitCommEvent() Failed. System Returned Error Code: " +
error.ToString();
return 0;
}
}
eventMask = (uint)Marshal.ReadInt32(evPtr);
return eventMask;
}