Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#程序在for循环中冻结_C#_Freeze - Fatal编程技术网

C#程序在for循环中冻结

C#程序在for循环中冻结,c#,freeze,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.

我这里有一段代码,它启动一个进程,等待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;
    }
}
for(int i=0;i<20;i++)
{
Process pro=新流程();
pro.StartInfo.FileName=@“C:\ProgramFiles(x86)\Mozilla Firefox\Firefox.exe”;
pro.StartInfo.WindowStyle=ProcessWindowStyle.Minimized;
pro.Start();
睡眠(8000);
尝试
{
pro.Kill();
睡眠(1000);
}
抓住
{
返回;
}
}

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

好吧,我最初的猜测是,您正在您的UI线程上执行这些操作。由于您使UI线程处于睡眠状态,因此应用程序将被冻结

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

正如Servy所说,这不是一个好主意。您可以使用计时器()进行等待,而不是阻塞UI线程

它是冰冻的。我不能移动它的窗口或点击其他按钮

没错。你说把线放在床上

人们似乎有一种奇怪的想法,即按下按钮时运行代码是靠魔法实现的。这不是魔法造成的。之所以会发生这种情况,是因为线程运行的代码处理来自操作系统的“单击了一个按钮”消息。如果你让一个线程进入睡眠状态,那么它就会停止处理这些消息,因为它处于睡眠状态

99%的情况下,让一根线睡觉是完全错误的,所以不要这样做


在C#5中正确的做法是使您的方法
异步
,然后执行
等待任务。延迟(无论什么)
。或者,创建一个计时器,在若干秒后滴答作响。在tick handling事件中,关闭计时器并在那里执行逻辑。

应用程序的主线程是一个循环,它不断地从Windows消息队列中窥视消息。这就像协作多线程——如果你不显式地更新你的用户界面,它就不会自动更新。这不会发生,因为您的程序(主线程)只是生成一个进程,然后休眠并杀死它(您甚至不需要
try/catch块
——应用程序任何线程上的任何异常都会终止它)。睡在一个线程中会阻塞它。因为您睡在主线程(UI)中,所以会阻止应用程序从消息队列中窥视。

这是因为Win表单是单线程的,没有出口的紧密循环不会给系统留下重新绘制表单或响应鼠标事件的空间。有什么解决方案可以避免这种情况吗?您需要异步完成工作,不同步,为了不阻止UI线程。@Jeremy小心,你可以在win forms应用程序中轻松使用线程,只是UI线程是他可能阻止的单个线程。我应该说“默认情况下”是单线程。Bradley正在创建一个新线程,这样它就可以无所事事~100%的时间是一个糟糕的主意。异步做得好意味着你有一个新线程,不是吗?更新了我的答案,建议使用计时器。@Robert:不,异步并不意味着并发。并发只是异步的一种。如果您在等待鸡蛋煮熟时决定将烤面包放入烤面包机,则使用异步。如果你决定雇佣两个厨师,一个做鸡蛋,一个做吐司,你就同时使用异步和并发。你认为哪个更便宜?@Robert这里有一个稍微长一点的解释:还有一个:我可能走错了方向,但我需要一些(线程?)不是我的UI线程来完成异步工作。我可以让一个厨师来做我的鸡蛋和烤面包机,但如果我是服务员,我就没有时间了。我有一个在后台运行的.NET应用程序,它必须以最轻松的方式执行操作,对系统的影响最小。我将消耗资源的调用与
Thread.Sleep(1)
调用交错。你认为这是可以接受的,还是有更好的方法来控制.NET中的资源使用?@LucaCremonesi:这绝对不是我会这样做的,我不知道你为什么会认为这有助于实现你的目标。你精确的、可测量的目标是什么?你收集了哪些经验证据证明这项技术达到了你的目标?你认为睡眠(1)有什么好处,比如说
收益率
?或者,如果你想让所有其他非空闲线程优先,那么简单地将线程的优先级设置为低于平均值又有什么错呢?@LucaCremonesi:我经常听到人们说他们希望CPU利用率低,我真的对此感到困惑。我花了很多钱买了那个CPU,我希望它能被使用!如果您的CPU一直以5%的容量运行,那么您肯定多付了20倍。@NumLock:实际上,
System.Threading.Timer
的回调是可重入的,因此在实现方法时必须考虑到这一点(从文档:“回调可以在两个线程池线程上同时执行…”)。