[英]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.