请看下面这段代码(著名的SPComm控件内的一段代码):
function TWriteThread.HandleWriteData( lpOverlappedWrite: POverlapped;
pDataToWrite: PChar; dwNumberOfBytesToWrite: DWORD): Boolean;
var
dwLastError,
dwNumberOfBytesWritten,
dwWhereToStartWriting,
dwHandleSignaled: DWORD;
HandlesToWaitFor: array[0..1] of THandle;
begin
Result := False;
dwNumberOfBytesWritten := 0;
dwWhereToStartWriting := 0; // Start at the beginning.
HandlesToWaitFor[0] := hCloseEvent;
HandlesToWaitFor[1] := lpOverlappedWrite^.hEvent;
// Keep looping until all characters have been written.
repeat
// Start the overlapped I/O.
if not WriteFile( hCommFile,
pDataToWrite[ dwWhereToStartWriting ],
dwNumberOfBytesToWrite, dwNumberOfBytesWritten,
lpOverlappedWrite ) then
begin
// WriteFile failed. Expected; lets handle it.
dwLastError := GetLastError;
// Its possible for this error to occur if the
// service provider has closed the port. Time to end.
if dwLastError = ERROR_INVALID_HANDLE then
Exit;
// Unexpected error. No idea what.
if dwLastError <> ERROR_IO_PENDING then
begin
PostHangupCall;
Exit
end;
// This is the expected ERROR_IO_PENDING case.
// Wait for either overlapped I/O completion,
// or for the CloseEvent to get signaled.
dwHandleSignaled := WaitForMultipleObjects(2, @HandlesToWaitFor,
False, INFINITE);
case dwHandleSignaled of
WAIT_OBJECT_0: // CloseEvent signaled!
begin
// Time to exit.
Exit
end;
WAIT_OBJECT_0 + 1: // Wait finished.
begin
// Time to get the results of the WriteFile
if not GetOverlappedResult(hCommFile,
lpOverlappedWrite^,
dwNumberOfBytesWritten, True) then
begin
dwLastError := GetLastError;
// Its possible for this error to occur if the
// service provider has closed the port.
if dwLastError = ERROR_INVALID_HANDLE then
Exit;
// No idea what could cause another error.
PostHangupCall;
Exit
end
end;
WAIT_FAILED: // Wait failed. Shouldn't happen.
begin
PostHangupCall;
Exit
end
else // This case should never occur.
begin
PostHangupCall;
Exit
end
end {case}
end; {WriteFile failure}
// Some data was written. Make sure it all got written.
Dec( dwNumberOfBytesToWrite, dwNumberOfBytesWritten );
Inc( dwWhereToStartWriting, dwNumberOfBytesWritten )
until (dwNumberOfBytesToWrite <= 0); // Write the whole thing!
// Wrote the whole string.
Result := True
end; {TWriteThread.HandleWriteData}
这段代码内只有一个Overlapped结构,基于我的所知道的有关Overlapped知识,
dwHandleSignaled := WaitForMultipleObjects(2, @HandlesToWaitFor,
False, INFINITE);//这里如果等待到lpoverlapp.hEvent信号.则系统肯定已经写完了所有的pDataToWrite指向的内存数据.
那么
GetOverlappedResult(hCommFile,
lpOverlappedWrite^,
dwNumberOfBytesWritten,
True)
这里lpOverlappedWrite 肯定已经等于dwNumberOfBytesToWrite(我认为是肯定的)
因为上面的WaitFor等出的信号说明系统已经(无折扣的)执行完Overlapped请求.
那么它为什么还要判断
Dec( dwNumberOfBytesToWrite, dwNumberOfBytesWritten );
Inc( dwWhereToStartWriting, dwNumberOfBytesWritten );
until (dwNumberOfBytesToWrite <= 0); // Write the whole thing!
再继续循环呢?