GetQueuedCompletionStatus - 如何识别已完成任务的“类型”?
GetQueuedCompletionStatus - how to identify the “type” of the finished task?
你能告诉我,当一个就绪任务出现在完成端口队列中,然后使用GetQueuedCompletionStatus函数检索它时,你如何知道这个就绪任务是用于读取还是写入?
一种常见的方法是编写一个从 Win32 (WSA)OVERLAPPED
结构派生的结构,或者将 (WSA)OVERLAPPED
作为其第一个数据成员。然后您可以将其他数据成员添加到您的结构中,以根据需要识别其任务、跟踪其状态等。
然后您可以为每个 I/O 操作分配一个结构实例,根据需要填充它,并将指向它的指针作为指向您选择的 I/O 的 (WSA)OVERLAPPED*
指针传递功能。
当 I/O 完成返回时,您可以将提供的 OVERLAPPED*
指针类型转换为指向您的结构类型的指针以访问其成员。
例如:
enum MY_OP_TYPE { opReading, opWriting };
struct MY_STRUCT : OVERLAPPED // or WSAOVERLAPPED
{
MY_OP_TYPE opType;
// other data members as needed...
MY_STRUCT()
{
Internal = 0;
InternalHigh = 0;
Offset = 0;
OffsetHigh = 0;
hEvent = NULL;
// other initializations as needed...
}
~MY_STRUCT()
{
// cleanups as needed...
// free hEvent if it is a (WSA)Event object...
}
// other methods as needed...
};
MY_STRUCT *ms = new MY_STRUCT;
ms->opType = opReading;
ms->hEvent = ...; // depending on which I/O function you are using, this could be a (WSA)Event object, or a pointer to opaque app data, etc...
// other assignments as needed...
...
if (IoReadingFunction(..., static_cast<OVERLAPPED*>(ms), ...) == FALSE /* or SOCKET_ERROR */)
{
if (GetLastError() != ERROR_IO_PENDING)
// or
// if (WSAGetLastError() != WSA_IO_PENDING)
{
...
delete ms;
}
}
...
OVERLAPPED *ov;
...
GetQueuedCompletionStatus(..., &ov, ... );
if (ov)
{
MY_STRUCT *ms = static_cast<MY_STRUCT*>(ov);
// use ms as needed...
switch (ms->opType)
{
...
}
...
delete ms;
}
你能告诉我,当一个就绪任务出现在完成端口队列中,然后使用GetQueuedCompletionStatus函数检索它时,你如何知道这个就绪任务是用于读取还是写入?
一种常见的方法是编写一个从 Win32 (WSA)OVERLAPPED
结构派生的结构,或者将 (WSA)OVERLAPPED
作为其第一个数据成员。然后您可以将其他数据成员添加到您的结构中,以根据需要识别其任务、跟踪其状态等。
然后您可以为每个 I/O 操作分配一个结构实例,根据需要填充它,并将指向它的指针作为指向您选择的 I/O 的 (WSA)OVERLAPPED*
指针传递功能。
当 I/O 完成返回时,您可以将提供的 OVERLAPPED*
指针类型转换为指向您的结构类型的指针以访问其成员。
例如:
enum MY_OP_TYPE { opReading, opWriting };
struct MY_STRUCT : OVERLAPPED // or WSAOVERLAPPED
{
MY_OP_TYPE opType;
// other data members as needed...
MY_STRUCT()
{
Internal = 0;
InternalHigh = 0;
Offset = 0;
OffsetHigh = 0;
hEvent = NULL;
// other initializations as needed...
}
~MY_STRUCT()
{
// cleanups as needed...
// free hEvent if it is a (WSA)Event object...
}
// other methods as needed...
};
MY_STRUCT *ms = new MY_STRUCT;
ms->opType = opReading;
ms->hEvent = ...; // depending on which I/O function you are using, this could be a (WSA)Event object, or a pointer to opaque app data, etc...
// other assignments as needed...
...
if (IoReadingFunction(..., static_cast<OVERLAPPED*>(ms), ...) == FALSE /* or SOCKET_ERROR */)
{
if (GetLastError() != ERROR_IO_PENDING)
// or
// if (WSAGetLastError() != WSA_IO_PENDING)
{
...
delete ms;
}
}
...
OVERLAPPED *ov;
...
GetQueuedCompletionStatus(..., &ov, ... );
if (ov)
{
MY_STRUCT *ms = static_cast<MY_STRUCT*>(ov);
// use ms as needed...
switch (ms->opType)
{
...
}
...
delete ms;
}