Note that there are some explanatory texts on larger screens.

plurals
  1. PODetect closed pipe in redirected console output in .NET applications
    text
    copied!<p>The .NET <code>Console</code> class and its default <code>TextWriter</code> implementation (available as <code>Console.Out</code> and implicitly in e.g. <code>Console.WriteLine()</code>) does not signal any error when the application is having its output piped to another program, and the other program terminates or closes the pipe before the application has finished. This means that the application may run for longer than necessary, writing output into a black hole.</p> <p><strong>How can I detect the closing of the other end of the redirection pipe?</strong></p> <p>A more detailed explanation follows:</p> <p>Here are a pair of example programs that demonstrate the problem. <code>Produce</code> prints lots of integers fairly slowly, to simulate the effect of computation:</p> <pre><code>using System; class Produce { static void Main() { for (int i = 0; i &lt; 10000; ++i) { System.Threading.Thread.Sleep(100); // added for effect Console.WriteLine(i); } } } </code></pre> <p><code>Consume</code> only reads the first 10 lines of input and then exits:</p> <pre><code>using System; class Consume { static void Main() { for (int i = 0; i &lt; 10; ++i) Console.ReadLine(); } } </code></pre> <p>If these two programs are compiled, and the output of the first piped to the second, like so:</p> <pre><code>Produce | Consume </code></pre> <p>... it can be observed that <code>Produce</code> keeps on running long after <code>Consume</code> has terminated.</p> <p>In reality, my <code>Consume</code> program is Unix-style <code>head</code>, and my <code>Produce</code> program prints data which is costly to calculate. I'd like to terminate output when the other end of the pipe has closed the connection.</p> <p>How can I do this in .NET?</p> <p>(I know that an obvious alternative is to pass a command-line argument to limit output, and indeed that's what I'm currently doing, but I'd still like to know how to do this since I want to be able to make more configurable judgements about when to terminate reading; e.g. piping through <code>grep</code> before <code>head</code>.)</p> <p><strong>UPDATE:</strong> It looks horribly like the <code>System.IO.__ConsoleStream</code> implementation in .NET is hard-coded to ignore errors 0x6D (<code>ERROR_BROKEN_PIPE</code>) and 0xE8 (<code>ERROR_NO_DATA</code>). That probably means I need to reimplement the console stream. Sigh...)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload