title: Windows named pipe dropping messages
body: <p>I am trying to write a named pipe reader to consume events from another application that provides named pipe streaming. I've run into a problem where I do not receive all events from the named pipe server when it sends batches of events very quickly together. </p>
  
  <p>To simplify the issue and isolate it from the other activity that is being done by the server application, I decided to cut it out and write a simple c++ console app that writes to a named pipe and have my code listen to that.</p>
  
  <p>After creating the test application to send batches of <strong>10</strong> messages with a three second wait between batches. The server indicates success for every write operation, but in the end my named pipe reader is consistently only receiving <strong>two</strong> messages.</p>
  
  <p>I tried adding in delays between read operations using Sleep(), and that had no effect. However, when I tried adding delays between write operations using Sleep() on the server, it allows me to receive the messages in the client.</p>
  
  <p>With batches of 10, a 1ms Sleep() will generally allow me to get all messages. If I send larger batches, I have to increase that Sleep() a bit.</p>
  
  <p>I tried reading with a simple C# app as well, and that did not improve my ability to read all events without delays between write operations.</p>
  
  <p>This is extremely confusing to me, because as I understand it the pipes are supposed to function as FIFO, so I have no idea where these messages are going.</p>
  
  <p>Does anyone have some insight into why these writes are successful, but I am unable to get all of them in the reader? Or why adding a small delay between the writes allows me to read them all just fine?</p>
  
  <p>I have included the writer and reader code below. I removed error handling/validation code to simplify the readability of it. For the server side piece, I got the pipe definition from the production app I'm trying to consume so I made sure the creation was the same.</p>
  
  <p><strong>Writer</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;windows.h&gt; 
  #include &lt;stdio.h&gt;
  #include &lt;conio.h&gt;
  #include &lt;tchar.h&gt;
  
  using namespace std;
  
  #define BUFFER_SIZE 65535
  
  int main()
  {
      HANDLE namedPipeHandle;
      BOOL   fSuccess = FALSE;
      DWORD  bytesRead;
  
      wstring pipeName = L"\\\\.\\pipe\\TestPipe";
  
      namedPipeHandle = CreateNamedPipe(pipeName.c_str(),
                                        PIPE_ACCESS_DUPLEX |FILE_FLAG_OVERLAPPED,
                                        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                                        PIPE_UNLIMITED_INSTANCES,
                                        BUFFER_SIZE,
                                        BUFFER_SIZE,
                                        NMPWAIT_USE_DEFAULT_WAIT,
                                        NULL);
  
      bool isConnected = ConnectNamedPipe(namedPipeHandle, NULL);
  
      DWORD bytesWritten = 0;
      string message = "TEST";
      int count = 0;
  
      while (true)
      {
          for (int i = 0; i &lt; 10; i++)
          {
              fSuccess = WriteFile(namedPipeHandle, message.c_str(), message.size(), &amp;bytesWritten, NULL);
  
              if (fSuccess)
              {
                  count++;
              }
  
              //Sleep(1); // Adding the Sleep(1) allows me to receive each batch of 10 in the client.
          }
          cout &lt;&lt; "Sent " &lt;&lt; count &lt;&lt; " total messages" &lt;&lt; endl;
          Sleep(3000);
      }
  }
  </code></pre>
  
  <p><strong>Reader</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;windows.h&gt; 
  #include &lt;stdio.h&gt;
  #include &lt;conio.h&gt;
  #include &lt;tchar.h&gt;
  
  using namespace std;
  
  #define BUFFER_SIZE 65535
  
  int main()
  {
      HANDLE hPipe;
      char buffer[BUFFER_SIZE];
      DWORD  bytesRead;
      wstring pipeName = L"\\\\.\\pipe\\TestPipe";
  
      hPipe = CreateFile(pipeName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
  
      int receivedCount = 0;
      int failedCount = 0;
  
      do
      {
          bool fSuccess;
  
          fSuccess = ReadFile(hPipe, buffer, BUFFER_SIZE, &amp;bytesRead, NULL);
  
          if (fSuccess)
          {
              receivedCount++;
          }
          else
          {
              failedCount++;
          }
  
          cout &lt;&lt; "Total Events Received: " &lt;&lt; receivedCount &lt;&lt; endl;
          cout &lt;&lt; "Total Events Failed: " &lt;&lt; failedCount &lt;&lt; endl;
      } while (true);
  
      CloseHandle(hPipe);
  
      return 0;
  }
  </code></pre>