0

我浏览了网上发布的几个示例,但我无法回答我的问题。

我的“p”变量在 for 循环中增加了 1。我希望 UI 显示计算进度(以显示“p”如何从 0 增加到 1000000)。我在单独的线程上进行计算,并调用调度程序来更新 UI 中的 ResultBox。例子:

 int p=0;

 ...

 private void GO(object sender, System.Windows.RoutedEventArgs e)
 {
        new Thread(delegate()
        {
            DoWork();
        }).Start();

}

    void DoWork()
    {
        for (int i = 0; i < 1000; i++)
        {
            for (int j = 0; j < 10000; j++)
            {
                p++;
                this.Dispatcher.BeginInvoke(delegate { ResultBox.Text = p.ToString(); });
            }
        }

    }

由于某种原因,这不起作用。但是,当我将 Thread.Sleep(1) 放在 this.Dispatcher... 之前时,它会按预期工作。这是否意味着 UI 更新(调度程序)被调用太频繁,因此它冻结了?还有其他方法吗?

谢谢

4

2 回答 2

1

为什么不将属性绑定到您的 TextBox 并更新属性值而不是直接戳文本框?

于 2010-07-08T16:10:00.880 回答
0

是的,仅在循环中执行 p++ 不会花费太多时间,并且在 silverlight 内部,Dispatcher 只不过是一个带有委托的简单队列,在 silverlight 甚至可以更新和处理其 UI 之前,您在队列中抽取了太多值。想象一下,如果您继续将队列方式添加到更快然后队列出队,那么最终它也会达到最大限制会发生什么。最终它会停止。如果将您的 p++ 替换为更耗时的任务,那么您可能会得到很好的结果。

您必须知道,我们的眼睛通常只能看到 30 fps 的更新,每秒超过 30 次更新根本没有任何用处,我建议您的视图更新应减少到每秒最多 10 次更新以获得最佳性能。

为了显示进度,我认为每秒 1 次更新也足够了。首先总是显示更新很慢,比如

void DoWork() 
{ 
    for (int i = 0; i < 1000; i++) 
    { 
        for (int j = 0; j < 10000; j++) 
        { 
            p++; 
            if((p % 1000)==0){
                 this.Dispatcher.BeginInvoke(delegate 
                      { ResultBox.Text = p.ToString(); });
            } 
        } 
    } 

} 

现在您可以将 1000 增加/减少到 10 的某个合适的倍数,以调整您的视觉更新。

于 2010-07-08T15:46:53.967 回答