0

I wrote the code below. I am calling this method to write to three different hard disks using three separate threads. One of the CancelIo calls is failing (returns false).

I assume that the disk is OK (the hardware is fine).

How can this be?

(After changing the disk I see it happening again on another disk.)

  public void foo(byte[] bufferToWrite)
  {
      unsafe
      {

            NativeOverlapped overlapped = new NativeOverlapped()
            {
                  EventHandle = eventHandle,
                  OffsetLow   = ( int )( s       & 0xffffffff ),
                  OffsetHigh  = ( int )( s >> 32 & 0xffffffff )
            };

            GCHandle gch = GCHandle.Alloc( bufferToWrite, GCHandleType.Pinned );
            IntPtr ptr = new IntPtr( ( void* )gch.AddrOfPinnedObject() );

            WriteFile( handle, ptr, length, ref bytesWritten, &overlapped );

            dwResult = WaitForSingleObject( EventHandle, 30000 );
            if(dwResult== TIME_OUT)
            {
                   Debug.Assert( CancelIo ( handle ) );

            }
      }
  }  
tshepang
  • 12,111
  • 21
  • 91
  • 136
Yanshof
  • 9,659
  • 21
  • 95
  • 195

1 Answers1

2

CancelIo fails if there are no outstanding IOs. Your IO might complete after 30001ms, just after the event wait ended with a timeout.

This race condition cannot be fixed. I know no better solution than to ignore the return value.

usr
  • 168,620
  • 35
  • 240
  • 369
  • 1
    And there would be no outstanding IOs if the WriteFile failed, which is probably what's happening. He needs to check the WriteFile return code and not call WaitForSingleObject if it fails. – Carey Gregory May 03 '12 at 22:51
  • ..not call WFSO unless the writeFile fails and (GetLastError Result == ERROR_IO_PENDING). – Martin James May 04 '12 at 12:56