0

I have a process that needs to launch a child process and communicate with it through standard input and output. The child process should be able to automatically terminate itself; however, I am having trouble closing the streams properly.

Here is the relevant code from the child / "client" process:

// This is started in a separate thread
private void watchStandardInput() {
    string line = null;
    do {
        try {
            line = Console.ReadLine();
        } catch (IOException) {
            return;
        }
        lock (inputWatcher) {
            switch (line) {
                // process command
            }
        }
    } while (line != null);
}

// This is called from the main thread
private void updateStatus(string statusMessage) {
    lock (inputWatcher) {
        Console.WriteLine(statusMessage);
    }
}

And here's the "server" code:

// This is in the main thread
using (StreamReader sr = process.StandardOutput) {
    while (!process.HasExited) {
        processOutput(sr.ReadLine());
    }
}

// Finally, commands are sent in a separate thread.

Now for the problem I am having: When the child process is supposed to be exiting, the server stays at sr.ReadLine() and the client stays at Console.ReadLine(). What am I doing wrong?

6
  • How is it supposed to be exiting? It looks at a glance like its just not exiting (I assume both of them waiting for input is its standard state? or is this an unusual state? At a crude level I would imagine setting a Property called "Child closing" that can be checked everywhere to ensure it doesn't try reading when it is meant to be closing but there are probably more elegant solutions, I just don't get your program flow well enough to know what they are at the moment. :) Commented Aug 12, 2010 at 15:47
  • Waiting for input is the standard state. The child process knows when it's supposed to close, but the parent doesn't. I could have the child do a Console.WriteLine("Hey I'm closing") but that's ugly and it would break existing code. Commented Aug 12, 2010 at 15:53
  • I should also mention that the child program is trying to close properly - but the threads remain blocked at the calls I mentioned above. Commented Aug 12, 2010 at 15:57
  • Is the client thread with ReadLine() a background thread, or if not, are you calling Thread.Abort() on it? If not, I think Chris is right and the client app isn't closing because that thread is sitting around waiting for input. Commented Aug 12, 2010 at 16:36
  • Yes, it's a background thread, and I tried calling Thread.Abort() on it. I'm well aware that the app isn't closing because that thread is sitting around waiting for input - my question is how can I get it to close? Commented Aug 12, 2010 at 16:50

1 Answer 1

2

Make sure the client thread doing the ReadLine() has IsBackground set to true. Do NOT do an Abort() / Join() on this thread. Just close down all non-background threads. I found that even with IsBackground set to true, doing an Abort() / Join() on the background thread caused my test app to wait for input, however, removing the Abort() / Join() and just exiting regularly worked fine.

Sign up to request clarification or add additional context in comments.

1 Comment

I was able to get something working by calling Environment.Exit in the child process when necessary, but this is a far better solution that I was not aware of. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.