title: USB HID communication with P/Invoke (Win32 API) and concurrent threads
body: <p>My goal is to create an application that is able to communicate with USB HID devices. The main (UI) thread creates the appropriate handle.</p>
  
  <pre><code> this.handle =
          Win32.CreateFile(
              devicePath,
              Win32.GENERIC_READ | Win32.GENERIC_WRITE,
              0,
              IntPtr.Zero,
              Win32.OPEN_EXISTING,
              Win32.FILE_FLAG_OVERLAPPED,
              IntPtr.Zero);
  </code></pre>
  
  <p>After this, two thread is started. The first is reading data from the device continuesly. If there is no available data, it is blocked. It uses overlapped reading. The handle could be passed to a FileStream object, but I have to used P/Invoke calls. My implementation is based on multiple HID libraries. So the thread runs the following loop:</p>
  
  <pre><code>while (true)
  {
      var overlapped = new Win32.Overlapped();
      overlapped.Offset = 0;
      overlapped.OffsetHigh = 0;
      overlapped.Event = this.readEvent;
  
      var readResult = 
          Win32.ReadFile(
              this.handle,
              buffer, 
              (uint)this.InputReportLength, 
              IntPtr.Zero, 
              ref overlapped);
  
      if (readResult == 0)
      {
          int errorCode = Marshal.GetLastWin32Error();
  
          // Overlapped operation is running =&gt; 0x3e5
          if (errorCode != 0x3e5)
          {
              break;
          }
      }
  
      var result = Win32.WaitForSingleObject(overlapped.Event, Win32.WAIT_INFINITE);
  
      if (result != Win32.WAIT_OBJECT_0 || this.handle == IntPtr.Zero)
      {
          // Handle is cleared
          break;
      }
  
      uint bytesRead = 0;
      Win32.GetOverlappedResult(this.handle, ref overlapped, out bytesRead, false);
  
      if (bytesRead &gt; 0)
      {
          byte[] report = new byte[this.InputReportLength];
          Array.Copy(buffer, report, Math.Min(bytesRead, report.Length));
  
          // Report data
          OnDataReceived(report);
      }
  }
  </code></pre>
  
  <p>The second thread consumes commands from a concurrent queue, marshals them into binary, then calls the following method that writes the data to the device.</p>
  
  <pre><code> IntPtr writeEvent = Win32.CreateEvent(IntPtr.Zero, false, true, Guid.NewGuid().ToString());
  
   var overlapped = new Win32.Overlapped();
   overlapped.Offset = 0;
   overlapped.OffsetHigh = 0;
   overlapped.Event = writeEvent;
  
   int writeResult = 
      Win32.WriteFile(
         this.handle, buffer, 
         (uint)buffer.Length,
         IntPtr.Zero, 
         ref overlapped);
  
   if (writeResult == 0)
   {
       int errorCode = Marshal.GetLastWin32Error();
  
       // Overlapped operation is running =&gt; 0x3e5
       if (errorCode != 0x3e5)
       {
           throw new IOException(string.Format("Cannot write device ({0})", errorCode));
       }
   }
  
   var result = Win32.WaitForSingleObject(writeEvent, Win32.WAIT_INFINITE);
  
   Win32.CloseHandle(writeEvent);
  
   if (result != Win32.WAIT_OBJECT_0)
   {
       throw new IOException("Failed to write");
   }
  </code></pre>
  
  <p>The application receives data pushed by the device correctly. The program just runs smoothly without any failure.
  <strong>BUT</strong> if the application sends data to the device (by placing command objects into the mentioned queue) the whole applications crashes <strong>spontaneously</strong>. The crash occurs in an indeterministic way. What is the reason behind this? My idea is that it is caused by the concurrent access. However, using the FileStream object (by passing the handle to it) concurrently do not result in such crash.</p>