Mal*_*ist 0 c# delegates readline streamreader
我有这个方法:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
它从进程(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;
}
}
Run Code Online (Sandbox Code Playgroud)
另一个有趣的是,它并不总是像它应该的那样隐藏cmd窗口.它第一次隐藏它,然后第二次(或之后)它不会隐藏它.这是用户可以关闭cmd.exe窗口并使readline行为有趣的时候.它也永远不会读取输出到cmd的最后一行,除非它退出.
对于如何解决这个问题,有任何的建议吗?
我会改变:
while(true)
Run Code Online (Sandbox Code Playgroud)
至:
while(!sr.EOS) {
}
Run Code Online (Sandbox Code Playgroud)
这是检查结束循环的更好方法.
每当你while(true)的代码中有一个循环时,你将以100%的方式将你的cpu(或至少一个核心)挂起,除非你还有办法摆脱循环.在你的情况下,你有一个return声明,但在循环中没有任何一点你做任何stop保护它的变量.
| 归档时间: |
|
| 查看次数: |
3914 次 |
| 最近记录: |