![](/img/trans.png)
[英]How can I use background worker(or any other solution) to stop freezing my GUI?
[英]How would I use Background Worker to get my GUI to respond?
我制作了一個只有一個按鈕的簡短程序。 當按下按鈕時,將執行功能A,該功能也將使用功能B和功能C。 在functionA內部是一個循環,循環執行functionB和functionC X次。 在每個循環的末尾,進度條將增加1。在功能A的開始處,在循環前,有一個Web服務將從網站上提取數據,並將其傳遞給B和C進行處理(將數據文件進行處理並保存到磁盤)。
我的問題是,一切正常,但是當functionA仍在運行時,GUI卡住了,因此我無法關閉/最小化/拖動周圍的窗口,我必須等到A完成之后。 我進行了研究,他們說我應該使用BackgroundWorker,但是作為一名新程序員,我不知道如何使用它。 有人可以給我一種簡單的使用方法嗎?
進度條可以很好地加載,但是僅僅是在函數運行時,整個窗口都被凍結了,所以我想要它,以便我可以在程序運行時四處移動窗口,而不必等到函數完成為止。
謝謝!
像下面這樣異步調用函數,它不會凍結UI。
private async void BeginProcessingAsync(Data d)
{
//Execute the long running task asynchronously
await Task.Run(() => functionA(d));
//Anything after the await line will be executed only after the task is finished.
anotherFunction(d); // if you have one..
}
要運行任務,只需調用BeginProcessingAsync(d);
。 另外,請注意:如果使用的是.NET的較新版本,則可能必須使用await Task.Factory.StartNew(() => functionA(d));
代替上面
總體而言,您需要確保您的GUI不會從其他線程更新。 而是,消息應轉到線程安全的位置。 例如 ,您可以將線程構建到類似數據庫的對象中,並讓GUI使用計時器來查找更新的數據標志。
在我看來, 馬克的答案是最簡單,最好的:
///...blah blah updating files
string newText = "abc"; // running on worker thread
this.Invoke((MethodInvoker)delegate {
someLabel.Text = newText; // runs on UI thread
});
///...blah blah more updating files
從Dotnet Perls :
后台工作程序使線程易於在Windows窗體中實現。 需要在另一個線程上完成繁重的任務,因此UI不會凍結。 完成任務后,有必要發布消息並更新用戶界面。
另外,如果您使用的是C#5,請從MSDN中查看基於任務的異步模式 (TAP)。
基於任務的異步模式(TAP)基於System.Threading.Tasks命名空間中的System.Threading.Tasks.Task和System.Threading.Tasks.Task類型,用於表示任意異步操作。 TAP是新開發的推薦異步設計模式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.