我有这个方法:
private delegate void watcherReader(StreamReader sr);
private void watchProc(StreamReader sr) {
while (true) {
string line = sr.ReadLine();
while (line != null) {
if (stop) {
return;
}
//Console.WriteLine(line);
line = stripColors(line);
txtOut.Text += line + "\n";
line = sr.ReadLine();
}
}
}
它从进程 (cmd.exe) 中读取流。当用户关闭 cmd.exe 窗口时,会导致 CPU 使用率跃升至 100%。使用调试器时,我看到它在 sr.ReadLine() 上停止并且永远不会返回。因为这是同时观察 StandardErrorStream 和 StandardOutputStream 它在两个内核上都使用 100%。
如果您需要,这里还有一些项目代码。
[DllImport("User32")]
private static extern int ShowWindow(int hwnd, int nCmdShow); //this will allow me to hide a window
public ConsoleForm(Process p) {
this.p = p;
p.Start();
ShowWindow((int)p.MainWindowHandle, 0); //0 means to hide the window.
this.inStream = p.StandardInput;
this.outStream = p.StandardOutput;
this.errorStream = p.StandardError;
InitializeComponent();
wr = new watcherReader(watchProc);
wr.BeginInvoke(this.outStream, null, null);
wr.BeginInvoke(this.errorStream, null, null);
}
public void start(string[] folders, string serverPath) {
this.inStream.WriteLine("chdir C:\\cygwin\\bin");
this.inStream.WriteLine("bash --login -i");
this.inStream.WriteLine("");
}
//code example from http://geekswithblogs.net/Waynerds/archive/2006/01/29/67506.aspx it is
//to make the textbox autoscroll I don't understand what it does, but it works.
#region autoscroll
[DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
const int WM_VSCROLL = 277;
const int SB_BOTTOM = 7;
private void txtOut_TextChanged(object sender, EventArgs e) {
IntPtr ptrWparam = new IntPtr(SB_BOTTOM);
IntPtr ptrLparam = new IntPtr(0);
SendMessage(((RichTextBox)sender).Handle, WM_VSCROLL, ptrWparam, ptrLparam);
}
#endregion
private void ConsoleForm_FormClosed(object sender, FormClosedEventArgs e) {
this.stop = true;
try {
this.p.Kill();
} catch (InvalidOperationException) {
return;
}
}
另一个有趣的是,它并不总是像应有的那样隐藏 cmd 窗口。它第一次隐藏它,然后第二次(或之后)它不会隐藏它。这是用户可以关闭 cmd.exe 窗口并使 readline 变得有趣的时候。它也永远不会读取输出到 cmd 的最后一行,除非它退出。
对于如何解决这个问题,有任何的建议吗?