使用C#异步模式更新UI的问题
我正在尝试实现此处显示的 MSDN 异步模式示例: http://msdn.microsoft.com/en-us/library/8wy069k1%28v=VS.90%29.aspx。在示例中,ProgressChanged 事件的触发频率很高,导致在处理事件时 UI 挂起。请注意,我将 startAsyncButton_Click 中的: 更改
int testNumber = rand.Next(200000);
为
int testNumber = 20000000;
以更好地测试此场景。
进度条确实按预期更新,但所有其他 UI 事件都挂起。如果我在 BuildPrimeNumberList 方法中更改
// Yield the rest of this time slice.
Thread.Sleep(0);
为
// Yield the rest of this time slice.
Thread.Sleep(1);
,UI 就会开始响应,这会破坏使用线程的性能目的。
在此示例中,任何人都可以推荐一种有效地允许 UI 保持响应的方法吗?
谢谢
I am attempting to implement the MSDN Asynchronous Pattern example shown here: http://msdn.microsoft.com/en-us/library/8wy069k1%28v=VS.90%29.aspx. In the example, the ProgressChanged event is fired with such frequency that the UI hangs while the events are being processed. Note that I changed:
int testNumber = rand.Next(200000);
to
int testNumber = 20000000;
in startAsyncButton_Click to better test this scenario.
The progress bar does update as expected, but all other UI events are hung. If I change
// Yield the rest of this time slice.
Thread.Sleep(0);
to
// Yield the rest of this time slice.
Thread.Sleep(1);
in the BuildPrimeNumberList method, the UI starts responding bit this defeats the performance purpose of using a thread.
Can anyone recommend an approach that effectively allows the UI to remain responsive in this example?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是 MSDN 上的一个误导性示例。对于在后台线程上执行工作并保持 UI 活动并了解后台进度的场景,请使用 BackgroundWorker 类。 http://msdn.microsoft.com/en-us/library /system.componentmodel.backgroundworker.aspx
This is a misleading example on MSDN. For the scenario of performing work on a background thread and keeping your UI active and informed of the background progress, use the BackgroundWorker class. http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
请注意示例中的注释,
我认为您的计算机速度太快,以至于产生了太多事件。
尝试更改报告间隔:
Note the comments from the example
I think your computer is so fast it is producing too many events.
Try changing the reporting interval:
在这种情况下,或者报告进度妨碍实际工作的任何其他情况下,关键是减少报告进度的频率,或者至少限制尝试的 UI 更新量。
此示例已经有一个机制:progressInterval 值确定进度事件导致 UI 更新的频率。我敢打赌这里的问题是每 100 次报告进度仍然太多了。
与其报告每 X 次重复(这不会随着处理器能力的增加而扩展),不如在每次 UI 更新时存储 DateTime,然后忽略再次更新 UI,直到至少过去 250-500 毫秒。
In this situation, or any other situation where reporting progress is getting in the way of doing the actual work, the key is to report progress less frequently, or at least to limit the amount of UI updating that is attempted.
This example already has a mechanism for that: the progressInterval value determines how often the progress event causes a UI update. I'll bet the problem here is that reporting progress every 100 times is still too much.
Instead of reporting every X repetitions (which will not scale along with increases in processor power) it might be a better idea to store the DateTime on each UI update, and then neglect to update the UI again until at least 250-500ms have gone by.