当前位置:  开发笔记 > 编程语言 > 正文

为什么我的循环使用100%CPU并且永远不会结束?

如何解决《为什么我的循环使用100%CPU并且永远不会结束?》经验,为你挑选了2个好方法。

我有这个方法:

    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的最后一行,除非它退出.

对于如何解决这个问题,有任何的建议吗?



1> jjnguy..:

我会改变:

while(true)

至:

while(!sr.EOS) {

}

这是检查结束循环的更好方法.



2> Joel Coehoor..:

每当你while(true)的代码中有一个循环时,你将以100%的方式将你的cpu(或至少一个核心)挂起,除非你还有办法摆脱循环.在你的情况下,你有一个return声明,但在循环中没有任何一点你做任何stop保护它的变量.

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有