目前工作的一个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