第 2 次尝试。尝试尽可能清楚,因为我从事这项任务的时间比我应该做的要长得多,而且进展甚微。
我需要为一个应用程序制作一个进度条。现在,一切都在一个 UI 线程中发生,所有的处理等等,所以当我在点击一个按钮后执行长时间运行的过程时,程序挂起大约 40 秒,然后恢复输出(我无法改变它部分,申请已交给我)。而且我还必须制作一个取消按钮,所以如果在中间过程中点击它,在该过程完成后,它会检查取消标志,如果它是 ON,则退出所有方法并返回到初始位置.
我要做的就是为这个过程做一个进度条。其中两个,一个用于中间过程,一个用于总过程。中间是一个小 Action ,像DB调用,输出中间过程(for和foreach循环)。
我试过将进度条放在同一个 UI 窗口中,并在我继续时在同一个线程中更新它们(找到主要点,在那里启动进度条并根据我的判断增加它们。和循环)。这只是加载了更多的 UI,但它正在运行(进度条移动不连贯)。
然后我尝试使用后台 worker 。同样,将条形图放在 UI 中并通过后台工作程序运行它们。问题是即使 BG worker 运行,刷新也必须发生在 UI 窗口中,它正忙于处理贪婪的请求,所以它没有在我想要的时候更新。
我尝试在核心使用多线程(没有 BG worker)并在新线程中创建一个新表单来反射(reflect)进度,但我被警告不要这样做(同时运行 2 个 UI 线程)并且我在传递值时遇到麻烦。更不用说如果使用线程方法,如果不完全使 CPU 过载(让另一个线程运行一段时间(true)并在您从某个点调用 updateMethod 时进行更新),就不可能准确地表示正在发生的进度过程)
我还有其他选择吗?因为最不消极的方面是我在执行程序时更新进度条的第一个方面。
最佳答案
我还有其他选择吗? 是和不是。最好的选择仍然是花时间学习如何正确使用 backgroundworker,这是迄今为止解决此问题的最简单的解决方案。
继续研究这些链接:
- Official MSDN Backgroundworker
- Step by Step Tutorial Number 1 (dotnetperls)
- Step by Step Tutorial Number 2 (dreamincode)
最重要的是设置这个属性:
bw.WorkerReportsProgress = true;
并且在 DoWork-Function 中,确保向 UI 报告进度,如链接示例中所示:
worker.ReportProgress((i * 10));
此外,不要忘记处理 UI 中的 progresschanged 事件:
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
}
继续,您会发现:它相当简单。
关于c# - 在 C# 中实现进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16616022/