procedure PerformAsynchronousRead( const fileName : string );
var
f : THandle;
overlaps : array[0..SIMULTANEOUS_OPERATIONS-1] of TOverlapped;
events : array[0..SIMULTANEOUS_OPERATIONS-1] of THandle;
desiredSize : DWORD;
readSize : DWORD;
readResult : Bool;
buffers : array[0..SIMULTANEOUS_OPERATIONS-1] of PInteger;
i : DWORD;
j : Integer;
value : Integer;
currentValue : PInteger;
begin
f := CreateFile( PChar(fileName),
GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED or FILE_FLAG_NO_BUFFERING, 0 );
if f = INVALID_HANDLE_VALUE then begin
WriteLn( 'Unable to open ' + fileName );
Exit;
end;
try
desiredSize := GetFileSize( f, nil ) div SIMULTANEOUS_OPERATIONS;
for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
events[i] := CreateEvent( nil, true, false, nil );
if events[i] = INVALID_HANDLE_VALUE then
RaiseLastOSError;
// Initialize the OVERLAPPED structure
FillChar(overlaps[i], SizeOf(overlaps[i]), 0);
overlaps[i].Offset := desiredSize * i;
overlaps[i].hEvent := events[i];
for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
// Request the data
readResult := ReadFile( f, buffers[i]^, desiredSize, readSize, @overlaps[i] );
if readResult then
WriteLn( 'Request performed as synchronous' )
else begin
if GetLastError = ERROR_IO_PENDING then begin
WriteLn( 'Request performed as ASYNCHRONOUS' );
WriteLn( 'Request queued...' );
end
else begin
RaiseLastOSError;
end;
end;
end;
// Do something useful here...
if WaitForMultipleObjects( SIMULTANEOUS_OPERATIONS,
PWOHandleArray(@events), true, INFINITE ) =
WAIT_FAILED then
RaiseLastOSError;
// Check result
for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
readResult := GetOverlappedResult( f, overlaps[i], readSize, False );
if not readResult then
RaiseLastOSError;
end;
WriteLn( 'Requests completed.' );
for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
VirtualFree( buffers[i], desiredSize, MEM_RELEASE );
CloseHandle( events[i] );
end;
finally
CloseHandle(f);
end;
end;