Getting a speed-bottleneck in data-communication when using anonymous pipes
<p>I have a program setup where a MCU sends me sensor data via USART to a C# windows forms application. That application upon receiving the data via the serialdatareceived event sends it to a managed c++ application using anonymous pipes. As soon as the data is received it is plotted in an OpenGL 3d enviroment.</p>

<p>My problem is that the 3D application only refreshes a few times per second and the animation is quite slow and not smooth enough. I did my best to improve the USART speed but the result is the same. I believe the animations speed is bottlenecked by the anonymous pipes speed. I was wondering if anyone else encountered this problem before and possibly found ways to speed upthe anonymous pipes data transfer.</p>

<p>So my problem is the low data transfer speed between the two applications. Ideally I would want 20+ messages a second but at the very least the bottleneck of the data transfer should be the USART interface and not the anonymous pipes. I am running a BAUD-rate of 19200 and am transferring the command "get_angle" and receiving data back fairly fast (~20 ms for calculation of data on the MCU), the data received is ~12 chars.</p>

<p>My anonymous pipe client in managed c++ (in WinMain):</p>

<pre><code>try
{
    String^ args = gcnew String(lpCmdLine);

    PipeStream^ pipeClient = gcnew AnonymousPipeClientStream(PipeDirection::In, args);
    StreamReader^ sr = gcnew StreamReader(pipeClient);

    String^ temp;

    fullscreen = FALSE;


    if (!CreateGLWindow("OpenGL Test", 640, 480, 16, fullscreen))
    {
        return 0;                                   // Quit If Window Was Not Created
    }

    while (!done)                                   // Loop That Runs While done=FALSE
    {
        if (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE))   // Is There A Message Waiting?
        {
            if (msg.message == WM_QUIT)             // Was the message a quit message?
            {
                done = TRUE;                            // Set Flag to execute program
            }
            else                                    // If Not, Deal With Window Messages
            {
                TranslateMessage(&amp;msg);             // Translate The Message
                DispatchMessage(&amp;msg);              // Dispatch The Message
            }
        }

        temp = sr-&gt;ReadLine();                      //  Read text from pipeline

        if (temp != "")                             // Make sure message is not empty/New message has been received
        {
            try
            {
                x_an = FLOAT::Parse(temp-&gt;Substring(0, 5));             // Parse X value from string to float
                y_an = FLOAT::Parse(temp-&gt;Substring(7, 12));            // Parse Y value from string to float
            }
            catch (Exception^)
            {
                MessageBox(NULL, "Error parsing string to float", "Fatal error", MB_OK);
            }
        }

        if ((!done)&amp;&amp; (1))
        {

            // Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
            if ((active &amp;&amp; !DrawGLScene()) || keys[VK_ESCAPE])  // Active?  Was There A Quit Received?
            {
                done = TRUE;                            // ESC or DrawGLScene Signalled A Quit
            }
            else                                    // Not Time To Quit, Update Screen
            {
                SwapBuffers(hDC);                   // Swap Buffers (Double Buffering)
            }

        }
    }
    // Shutdown
    sr-&gt;Close();
    pipeClient-&gt;Close();

    KillGLWindow();                                 // Kill The Window
    return (msg.wParam);                            // Exit The Program
}
catch (Exception^)
{
    MessageBox(NULL, "Pipe connection error", "Fatal error", MB_OK);
    return 0x01;
}
</code></pre>

<p>My code for the C# anonymous pipes server part:</p>

<pre><code>private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (Ready_To_Receive)
        {
            if (Setup_Pipe)
            {
                try
                {
                pipeClient.StartInfo.FileName = "client.exe";
                pipeClient.StartInfo.Arguments =
                pipeServer.GetClientHandleAsString();
                pipeClient.StartInfo.UseShellExecute = false;
                pipeClient.Start();

                pipeServer.DisposeLocalCopyOfClientHandle();

                sw = new System.IO.StreamWriter(pipeServer);

                sw.AutoFlush = true;

                Setup_Pipe = false;
                }
                catch
                {
                    MessageBox.Show("Error setting up pipeserver.");
                    button2_Click(this, null); // Resets application
                }
            }
            Debug_String = serialPort1.ReadExisting();
            Debug_String = Debug_String.Replace(serialPort1.NewLine, "");                           // Delete newline character so all that remains are numbers

            if (!(Debug_String == ""))                        // String is not empty
            {
                DataReceived = true;
                try
                {
                    sw.WriteLine(Debug_String);
                }
                catch (Exception)
                {
                    MessageBox.Show("Connection to Pipe Client lost.");
                    button2_Click(this, null);
                }

            }
        }
        else if (Shutting_Down)
        {
            pipeClient.Close();
        }
        else
        {
        serialPort1.ReadExisting(); // Flush the data buffer
            DataReceived = true;
        }
    }
</code></pre>