C++ 未调用ReadFileEx()完成例程
我正在编写一个类(C++ 未调用ReadFileEx()完成例程,c++,windows,winapi,asynchronous,overlapped-io,C++,Windows,Winapi,Asynchronous,Overlapped Io,我正在编写一个类(PipeReader)来处理Windows上的命名管道。该类使用异步IO从管道中读取 到目前为止,我一直在一个没有事件循环的线程中使用该类,我不得不等待IO完成使用SleepEx(),它成功了 现在我有了一个带有事件循环的第二个线程和PipeReader类的第二个实例,但是从未调用第二个实例的完成例程 调用CreateFile(): 调用ReadFileEx(): 用于在线程1中等待的代码,该代码有效: while (SleepEx(msecs < 0 ? INFINIT
PipeReader
)来处理Windows上的命名管道。该类使用异步IO从管道中读取
到目前为止,我一直在一个没有事件循环的线程中使用该类,我不得不等待IO完成使用SleepEx()
,它成功了
现在我有了一个带有事件循环的第二个线程和PipeReader
类的第二个实例,但是从未调用第二个实例的完成例程
调用CreateFile()
:
调用ReadFileEx()
:
用于在线程1中等待的代码,该代码有效:
while (SleepEx(msecs < 0 ? INFINITE : msecs, TRUE) == WAIT_IO_COMPLETION) {
if (m_readFinished) // Set to true in the completion routine
return true;
msecs = // decrease msecs by the amount elapsed
if (!msecs)
break;
}
编辑:
如果我将MsgWaitForMultipleObjectsEx()
的调用替换为:
WaitForSingleObjectEx(m_hwnd, INFINITE, TRUE);
它仍然不起作用。但是,如果我在事件循环中使用
SleepEx()
,它会工作。这是因为m\u hwnd
不是内核句柄。因此,WaitForSingleObjectEx
失败,而WAIT\u失败
和GetLastError
返回ERROR\u INVALID\u句柄
——因此线程永远不会进入可警报的等待,也永远不会执行APC。您需要另一个消息循环,例如:
for ( ; ; ) {
MSG msg;
switch(MsgWaitForMultipleObjectsEx(0, 0, INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE| MWMO_ALERTABLE))
{
case STATUS_WAIT_0 :
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
switch(msg.message) {
case WM_QUIT:
return;
default:
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
case WAIT_IO_COMPLETION :
// apc called
continue;
default: return ;
}
谢谢,这很有效。我有一个错误的想法,那就是我必须等待HWND能够使用
PostMessage()
@BenjaminT()唤醒它。不,你不需要等待HWND(而且不能)。您需要准确地第一次调用MsgWaitForMultipleObjectsEx
,并且仅当它返回STATUS\u WAIT\u 0
+n(其中n个句柄计数)时,才需要在循环中调用PeekMessage
,而它返回true
forever()
{
forever()
{
bool haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
if (haveMessage)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
break; //No message leave loop
}
}
HANDLE handles[1];
handles[0] = m_hwnd;
DWORD result = MsgWaitForMultipleObjectsEx(1, handles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE|MWMO_INPUTAVAILABLE);
}
WaitForSingleObjectEx(m_hwnd, INFINITE, TRUE);
for ( ; ; ) {
MSG msg;
switch(MsgWaitForMultipleObjectsEx(0, 0, INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE| MWMO_ALERTABLE))
{
case STATUS_WAIT_0 :
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
switch(msg.message) {
case WM_QUIT:
return;
default:
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
case WAIT_IO_COMPLETION :
// apc called
continue;
default: return ;
}