2010-08-12 158 views
0

我有一个需要启动子进程并通过标准输入和输出与它通信的进程。子进程应该能够自动终止;但是,我无法正确关闭流。C# - 如何在进程退出时关闭标准输入和输出流?

这里是孩子/ “客户端” 过程中的相关代码:

// 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); 
    } 
} 

而这里的 “服务器” 代码:

// 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. 

现在对于我有问题:当子进程应该退出时,服务器停留在sr.ReadLine(),客户端停留在Console.ReadLine()。我究竟做错了什么?

+0

它应该如何退出?它看起来就像它刚刚没有退出一样(我假设他们都在等待输入是它的标准状态?还是这是一个不寻常的状态?在粗略的水平上,我会想象设置一个名为“儿童关闭”的属性,可以检查无处不在,以确保它在尝试关闭时不会尝试读取,但有可能是更优雅的解决方案,我只是没有足够好地了解您的程序流程,以便知道他们目前的状态。) – Chris 2010-08-12 15:47:33

+0

等待输入是标准状态。子进程知道应该何时关闭,但父进程不知道。我可以让孩子做一个'Console.WriteLine(“嘿,我正在关闭”),但这很丑陋,会破坏现有的代码。 – jnylen 2010-08-12 15:53:02

+0

我还应该提到,子程序正在_trying_正常关闭 - 但是线程在我上面提到的调用中仍然被阻止。 – jnylen 2010-08-12 15:57:28

回答

1

确保执行ReadLine()的客户端线程将IsBackground设置为true。不要在这个线程上做一个Abort()/ Join()。关闭所有非后台线程。我发现即使将IsBackground设置为true,在后台线程上执行Abort()/ Join()也会导致我的测试应用程序等待输入,但是,取消Abort()/ Join()并退出正常工作正常。

+0

我可以在必要时通过在子进程中调用'Environment.Exit'来获得某些工作,但这是一个更好的解决方案,我不知道。谢谢。 – jnylen 2010-08-12 18:40:22

相关问题