【发布时间】:2010-12-29 11:03:53
【问题描述】:
我想在做一些工作时显示一个进度条,但这会挂起 UI 并且进度条不会更新。
我有一个带有ProgressBar 的 WinForm ProgressForm,它将无限期地以 marquee 方式继续。
using(ProgressForm p = new ProgressForm(this))
{
//Do Some Work
}
现在有很多方法可以解决这个问题,比如使用BeginInvoke,等待任务完成并调用EndInvoke。或使用BackgroundWorker 或Threads。
我在 EndInvoke 方面遇到了一些问题,但这不是问题所在。问题是哪种是处理此类情况的最佳和最简单的方法,您必须向用户展示程序正在运行且不会无响应,以及如何使用最简单的代码来处理它,该代码可能高效且成功' t 泄漏,并且可以更新 GUI。
像BackgroundWorker 需要有多个函数,声明成员变量等。你还需要持有对ProgressBar Form 的引用并处理它。
编辑:BackgroundWorker 不是答案,因为我可能没有收到进度通知,这意味着不会调用ProgressChanged,因为DoWork 是一次调用外部函数,但我需要继续调用Application.DoEvents(); 以使进度条保持旋转。
赏金是针对此问题的最佳代码解决方案。我只需要调用Application.DoEvents() 以便 Marque 进度条可以工作,而辅助函数在主线程中工作,它不会返回任何进度通知。我从不需要 .NET 魔术代码来自动报告进度,我只需要一个比以下更好的解决方案:
Action<String, String> exec = DoSomethingLongAndNotReturnAnyNotification;
IAsyncResult result = exec.BeginInvoke(path, parameters, null, null);
while (!result.IsCompleted)
{
Application.DoEvents();
}
exec.EndInvoke(result);
使进度条保持活动状态(意味着不冻结但刷新标记)
【问题讨论】:
-
这适用于哪个版本的 .NET?
-
@Priyank - BackgroundWorker 如果您没有收到进度更新通知,您打算如何更新进度条?
-
@Paolo:它的商标,无限轮换,我只希望用户正在进行一些处理。
-
如果您的进度条只是在旋转直到您的后台任务完成,为什么还要为所有的复杂性而烦恼呢?只需在 UI 线程上运行动画:如果您使用任何合理的方法启动后台任务,则后台任务不会阻塞 UI。在完成通知时终止动画。
-
@Godeke:我想在主线程上运行所谓的后台任务,而不是使用任何合理的方法,如线程、BackgroundWorker、SyncronizationContext。
标签: c# multithreading .net-3.5 begininvoke