我将如何使用后台工作来获得我的GUI响应
本文关键字:我的 GUI 响应 工作 何使用 后台 | 更新日期: 2023-09-27 18:04:00
我编写了一个只有一个按钮的短程序。当按钮被按下时,执行functionA,它也使用functionB和functionC。在函数a内部是一个循环,执行函数b和函数c X次。在每个循环结束时,进度条增加1。在函数a的开头,在循环之前,有一个webservice从网站中提取数据,并将其传递给B和C进行处理(数据文件操作并保存到磁盘)。
我的问题是一切都很好,但是当函数A仍在运行时,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使用计时器来查找更新的数据标志。
这里有一个关于委托的更多细节的问题。
Marc的回答在我看来是最简单也是最好的:
///...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
From Dotnet perl :
一个后台工作线程使线程在Windows中易于实现形式。密集的任务需要在另一个线程上完成,所以UI不冻结。发布消息和更新用户是必要的接口。
另外,从MSDN,如果你正在使用c# 5,看看基于任务的异步模式(TAP)。
基于任务的异步模式(TAP)基于System.Threading.Tasks.Task和System.Threading.Tasks.Task类型在System.Threading.Tasks命名空间中,用于表示任意异步操作。TAP是推荐的用于新开发的异步设计模式。