2015-10-06 99 views
4

我正在为使用事件驱动方法进行串行端口通信的win32编程提出问题。我有我的通讯手柄创建为:WriteFile在使用WaitCommEvent时挂起应用程序

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); 

我Wrifile去转换成当WM_CHAR被触发时向通信设备发送字符的WndProc:

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

我不太记得,但我认为你需要一个'FILE_FLAG_OVERLAPPED'在你的实现中。如果它可以帮助你看看我的旧的旧的旧的CBuilder Com Port组件[这里](http://sourceforge.net/projects/tlpscomport/) – LPs

+0

它是没有意义的,它会阻止。寻找不平凡的错误。 'str'没有正确的零终止,很容易出错,有些东西会爆炸。并尝试另一个USB模拟器,周围有很多垃圾。 –

+0

你可以发布写入端口的实际代码吗?在当前代码中,你发送的是未初始化的堆栈垃圾,我希望这不是你实际做的。 – theB

回答

-1

这是同步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后面的代码将不会被执行。

但是,在极端情况下,在WndProc进入WriteFile之前,调用ReadFile函数的线程会重新调用WaitCommEvent函数。如果发生这种情况,需要分开处理。 WaitCommEvent返回FALSE时可能会延迟一段时间。

相关问题