目前工作的一個Windows窗體應用程序,我要求創建。我遇到了一個在調用資源密集型進程時UI凍結的問題。我目前正在使用線程,據我所知,該線程用於防止UI凍結並接管整個PC。
問題
目前,當我使用的線程中調用我的基類中的方法是打開位於遠程服務器上的文件。這種方法有大約30到45秒的延遲。我正在創建我的後臺線程並調用它來啓動。當被調用時啓動,如果觸發,但是當它啓動時,不會等待我的線程完成,基本上給我一個空的異常。所以經過一番挖掘,我發現爲了等待線程完成,你必須調用.Join()
。但是,當Join被調用時,它完全凍結了我的UI。所以我的創造力試圖創造一個工作周圍,並創建一個while循環,直到線程不再活着並繼續。但是,這也會凍結用戶界面。所以我錯過了什麼?未提及MSDN Doc
代碼示例
class BaseClass
{
public CWClient ClientFileContext(string clientFile, bool compress)
{
Client clientContext = null;
try
{
if (compress == true)
{
clientContext = appInstance.Clients.Open2(clientFile, superUser, passWord, OpenFlags.ofCompressed);
}
else
{
clientContext = appInstance.Clients.Open2(clientFile, superUser, passWord, OpenFlags.ofNone);
}
}
catch (Exception ex)
{
//TODO
}
return clientContext;
}
}
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
BaseClass wpSec = new BaseClass();
CWClient client = null;
Thread backgroundThread = new Thread(
new ThreadStart(() =>
{
client = wpSec.ClientFileContext(selectedFileFullPath, true);
}
));
backgroundThread.Start();
//backgroundThread.Join(); << Freezes the UI
var whyAreYouNotWorking = "Stop";
}
}
解決方法我試過
while (backgroundThread.IsAlive == true)
{
for (int n = 0; n < 100; n++)
{
Thread.Sleep(500);
progressBar1.BeginInvoke(new Action(() => progressBar1.Value = n));
}
}
// This also freezes the UI
是的,加入(立即在開始之後)否定了整個線程設置。你期望什麼?它也會使任何Control.Invoke()調用發生死鎖。 –
這裏的簡單答案是使用BackgroundWorker –
所以你知道,如果你阻止你的UI線程並強制它在你的後臺工作完成之前什麼都不做,你的UI將被凍結,而當你不這樣做的時候,它不會。所以......你的問題是什麼?你已經知道如何解決你的問題,*不要阻塞UI線程*。您已經顯示了代碼不要自行阻止UI線程。 – Servy