2015-03-31 130 views
0

我有這裏的代碼,啓動一個進程等待8秒,然後殺死它,並再次。C#程序凍結for循環

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啓動時,它會成功啓動並終止進程,但它被凍結。我不能移動它的窗口或點擊其他按鈕..

+5

這是因爲Win表單是單線程的,並且沒有退出的緊密循環不會讓系統重新繪製表單或響應鼠標事件。 – Jeremy 2015-03-31 17:33:20

+0

任何解決方案逃避這個? – Dionisis 2015-03-31 17:33:59

+0

不這樣做...... – Jeremy 2015-03-31 17:34:09

回答

1

那麼,我最初的猜測是,你在你的UI線程上做這一切。由於您使UI線程處於睡眠狀態,因此您的應用程序將被凍結。

明顯的解決方案將在一個新的線程中做到這一點。

由於Servy sais,這不是一個好主意。您可以使用定時器(https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx)來執行等待,而不是阻塞UI線程。

+2

創建一個新線程只是爲了讓它可以坐在一起無所事事〜100%的時間是一個可怕的想法。 – Servy 2015-03-31 17:36:12

+0

@Servy你有什麼建議? – Dionisis 2015-03-31 17:38:14

+0

異步完成工作。這就是桌面用戶界面101. – Servy 2015-03-31 17:39:20

12

它被凍結。我不能移動窗口或點擊其他按鈕。

這是正確的。你說要把線頭睡覺。

人們似乎有這種奇怪的想法,按下按鈕時運行代碼發生的魔術。它不會發生魔法。它發生是因爲線程運行處理從操作系統中「單擊按鈕」消息的代碼。如果你把一個線程休眠,那麼它會停止處理這些消息,因爲它睡着了。

讓線程進入睡眠是99%的時間完全錯誤的事情,所以不要這樣做。

在C#5中做正確的事情是讓你的方法async然後做一個await Task.Delay(whatever)。或者,創建一個計時器,在幾秒鐘後打勾。在tick處理事件中,關閉定時器並在那裏執行你的邏輯。

+1

我有一個在後臺運行的.NET應用程序,它必須以最輕的方式執行其操作,並且對系統的影響最小。我用'Thread.Sleep(1)'調用了消耗資源的調用。你認爲這是可以接受的,還是有更好的方法來控制.NET中的資源使用情況? – 2015-03-31 19:01:19

+4

@LucaCremonesi:這絕對不是我會這麼做的方式,我不知道爲什麼你會認爲這會幫助你實現你的目標。你準確的,可衡量的目標是什麼?你收集的經驗證據是這種技術能達到你的目標嗎?你認爲'睡眠(1)'已經結束了,說'收益'有什麼好處? – 2015-03-31 20:28:27

+2

或者,如果您希望所有其他非空閒線程優先,那麼簡單地設置線程的優先級低於平均值會出現什麼問題? – 2015-03-31 20:38:42

0

您的應用程序的主線程是一個不斷從Windows消息隊列中查看消息的循環。這就像協作式多線程 - 如果您不明確更新您的用戶界面,它將不會自動執行。它不會因爲你的程序(主線程)產生了一個進程然後會休眠然後殺死它(你甚至不需要那個 - 任何應用程序的任何線程的異常都會終止它)。睡在一個線程內阻塞它。而且,因爲你睡在主線程(UI)中,所以阻止應用程序從消息隊列中窺視。