C#程序在for循环中冻结

时间:2015-03-31 17:31:20

标签: c# freeze

我这里有这个代码,开始一个进程等待8秒,然后再次杀死它。

for (int i = 0; i < 20; i++)
{
    Process pro = new Process();
    pro.StartInfo.FileName = @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
    pro.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
    pro.Start();

    Thread.Sleep(8000);

    try
    {
        pro.Kill();
        Thread.Sleep(1000);
    }
    catch
    {
        return;
    }
}

当我在调试模式或直接从.exe运行应用程序时,它成功启动并终止进程但它被冻结。我无法移动窗口或点击其他按钮..

3 个答案:

答案 0 :(得分:12)

  它冻结了。我无法移动窗口或点击其他按钮。

这是对的。你说让线程入睡。

人们似乎有这样一个奇怪的想法,按下按钮时运行代码是由魔术发生的。它不是通过魔法发生的。之所以会发生这种情况,是因为该线程运行的代码处理来自操作系统的“单击按钮”消息。如果你让一个线程进入休眠状态,它就会停止处理这些消息,因为它已经睡着了。

让一个线程进入睡眠是99%的时间完全错误的事情,所以不要这样做。

在C#5中正确的做法是制作方法async,然后执行await Task.Delay(whatever)。或者,创建一个在几秒钟后滴答的计时器。在刻度处理事件中,关闭计时器并在那里执行逻辑。

答案 1 :(得分:1)

好吧,我最初的猜测是你在你的UI线程上做了这一切。由于您使UI线程处于休眠状态,因此您的应用程序将被冻结。

显而易见的解决方案是在新线程中执行此操作。

作为Servy sais,这不是一个好主意。您可以使用计时器(https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx)进行等待,而不是阻止UI线程。

答案 2 :(得分:0)

应用程序的主线程是一个循环,它不断地从Windows消息队列中查看消息。它就像合作多线程一样 - 如果你没有明确更新你的用户界面,它就不会自动做到这一点。并且它不会因为你的程序(主线程)产生一个进程然后睡觉然后杀死它(你甚至不需要那个try/catch block - 你的应用程序的任何线程上的任何异常将终止它)。睡在一个线程中阻止它。并且因为您在主线程(UI)中睡眠,所以阻止应用程序从消息队列中窥视。