我正在使用事件驱动的方法来解决使用win32编程进行串行端口通信的问题。我的通信句柄创建为:
hComm = CreateFile(lpszCommName, GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, 0, NULL);
我将我的CommTimeouts设置为:
commTimeout.ReadIntervalTimeout = MAXWORD;
commTimeout.ReadTotalTimeoutConstant = 0;
commTimeout.ReadTotalTimeoutMultiplier = 0;
commTimeout.WriteTotalTimeoutConstant = 0;
commTimeout.WriteTotalTimeoutMultiplier = 0;
我为ReadFile创建了一个如下所示的线程:
SetCommMask(hComm, EV_RXCHAR);
while (isConnected)
{
if (WaitCommEvent(hComm, &dwEvent, NULL)) //If i comment out this block my write file will work fine
{
ClearCommError(hComm, &dwError, &cs);
if ((dwEvent & EV_RXCHAR) && cs.cbInQue)
{
if (!ReadFile(hComm, str, cs.cbInQue, &read_byte, NULL))
/* Process error*/
else if (read_byte)
/* Print to screen */
}
else {
/* Process error*/
}
}
}
PurgeComm(hComm, PURGE_RXCLEAR);
My Wrifile进入WndProc,当WM_CHAR被触发时,它会向通信设备发送字符:
VOID Write_To_Serial(WPARAM wParam, HWND hwnd){
DWORD write_byte;
char str[10];
sprintf_s(str, "%c", (char)wParam); //Convert wParam to a string
WriteFile(hComm, str, strlen(str), &write_byte, NULL)//Program hangs here
}
我的问题是每次WriteFile()被调用我的应用程序挂起,我必须强制关闭它。如果我在我的读取线程中注释掉WaitCommEvent()它工作正常,但我无法阅读。任何指针都将不胜感激。感谢
答案 0 :(得分:0)
这是同步IO操作的预期行为。
根据MSDN(https://msdn.microsoft.com/en-us/library/ff802693.aspx)中的串行通信文章中的以下描述,
应用程序负责序列化访问 端口正确。如果一个线程被阻塞等待其I / O操作 完成,随后调用通信的所有其他线程 API将被阻止,直到原始操作完成。对于 例如,如果一个线程正在等待ReadFile函数 返回,发出WriteFile函数的任何其他线程都是 阻止。
WriteFile必须等到WaitCommEvent函数完成其操作。
当需要调用WriteFile时,一个小的解决方法是取消挂起的WaitCommEvent操作(例如通过使用CancelIoEx API)。
VOID Write_To_Serial(WPARAM wParam, HWND hwnd){
DWORD write_byte;
char str[10];
sprintf_s(str, "%c", (char)wParam); //Convert wParam to a string
CancelIoEx(hComm, NULL);
WriteFile(hComm, str, strlen(str), &write_byte, NULL);//Program hangs here
}
WaitCommEvent在取消时返回FALSE。因此,WaitCommEvent之后的代码将不会被执行。
但是,在极端情况下,调用ReadFile函数的线程有可能在WndProc到WriteFile之前重新调用WaitCommEvent函数。如果发生这种情况,则需要单独处理。当WaitCommEvent返回FALSE时,可能会有一点延迟。