title: Parse output from a process that updates a single console line
body: <p>Greetings stackoverflow members,</p>
  
  <p>in a BackgroundWorker of a WPF Frontend i run <a href="http://sox.sourceforge.net/" rel="nofollow">sox</a> (open source console sound processing tool) in a <code>System.Diagnostics.Process</code>. In that same way i use several other command line tools and parse their output to poulate progress bars in my frontend.</p>
  
  <p>This works fine for the other tools but not for Sox since instead of spamming new lines for each progress step, it updates a single line on the console by only using carriage returns (\r) and no line feeds (\n). I tried both asynchronous and synchronous reads on <code>process.StandardError</code>.</p>
  
  <p>Using async <code>process.ErrorDataReceived += (sender, args) =&gt; FadeAudioOutputHandler(clip, args);</code> in combination with <code>process.BeginErrorReadLine();</code> doesn't produce any individual status updates because for some reason the carriage returns do not trigger ReadLine, even though the <a href="http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline%28v=VS.100%29.aspx" rel="nofollow">MSDN docs</a> suggest that it should. The output is spit out in one chunk when the process finishes.</p>
  
  <p>I then tried the following code for synchronous char by char reads on the stream:</p>
  
  <pre><code>char[] c;
  var line = new StringBuilder();
  while (process.StandardError.Peek() &gt; -1)
  {
      c = new char[1];
      process.StandardError.Read(c, 0, c.Length);
      if (c[0] == '\r')
      {
          var percentage = 0;
          var regex = new Regex(@"%\s([^\s]+)");
          var match = regex.Match(line.ToString());
          if (match.Success)
          {
              myProgressObject.ProgressType = ProgressType.FadingAudio
              //... some calculations omitted for brevity
              percentage = (int) Math.Round(result);
          }
          else
          {
              myProgressObject.ProgressType = ProgressType.UndefinedStep;
          }
          _backGroundWorker.ReportProgress(percentage, myProgressObject);
          line.Clear();
      }
      else
      {
          line.Append(c[0]);
      }
  }
  </code></pre>
  
  <p>The above code does not seem to read the stream in realtime but will stall output for a while. Then it spams a small chunk and finally deadlocks half-way through the process.</p>
  
  <p>Any hints towards the right direction would be greatly appreciated!</p>
  
  <p><strong>UPDATE with (sloppy?) solution:</strong></p>
  
  <p>This drove me crazy because nothing i tried on the C# side of things seemed to have any effect on the results. My original implementation, before changing it 15 times and introducing new dependencies, was fine.</p>
  
  <p>The problem is with sox and RedirectStandardError alone. I discovered that after grabbing the sox source code and building my own version. First i removed all output of sox entirely except for the stuff i was really interested in and then changing the output to full lines followed by a newline <code>\n</code> . I assumed that this would fix my issues. Well, it didn't. I do not know enough c++ to actually find out why, but they seem to have tempered with how stdio writes to that stream, how it's buffered or do it in such a special way that the streamreader on the c# side is not flushed until the default 4096 byte buffer is full. I confirmed that by padding each line to at least 4096 byte. So in conclusion all i had to do was to manually flush stderr in sox.c after each <code>fprintf(stderr, ...)</code> call in <code>display_status(...)</code>:</p>
  
  <pre><code>fflush(stderr);
  </code></pre>
  
  <p>Though, I'm not sure this is anywhere close to an elegant solution.</p>
  
  <p>Thanks to Erik Dietrich for his answer which made me look at this from a different angle.</p>