写了个小小的测试程序,在Winform分别加了一个Winform的ProcessBar和WPF的ProcessBar,再加一个button, 下面是button Click事件的代码:
private void button1_Click(object sender, EventArgs e)
        {
            mWinformProgressBar.Value = 0;
            mWPFProcessBar.Value = 0;
            double d = 0.0f;
            for (int i = 0; i < 1000; i++)
            {
                for (int j = 0; j < 100000; j++)
                {
                    d = (double)i / (j + 1);
                }
                mWinformProgressBar.Value += 1;
                mWPFProcessBar.Value += 1;
            }
        }
个人先前预期的结果是: 界面没反应,两个ProcessBar都没有反应直到循环结束。
但实际运行结果有点出乎我的预料: 界面没反应,WPF的ProcessBar也没反应,但Winform的ProcessBar却能时时更新。谁能帮我解释下呢,能给出些相关的参考资料更好。如果在每个小循环里加System.Windows.Forms.Application.DoEvents(), WPF的ProcessBar也能几时更新,我想知道有没有其他方法也能让WPF时时更新.(另起 System.Threading下的线程除外)

解决方案 »

  1.   

    wpf下的多线程写法确实跟winform下的不一样,我当初平移winform下的时候就遇到过这个问题.
    不过说实在的,具体什么原因我不是很懂,毕竟是做bs出身的,不过后来一个同事用一个叫什么dispatcher(名字可能有误)的东西实现了.
    楼主可以用那个方法试一试,希望能帮到你.
      

  2.   

    不管是Winform还是WPF都应该加上System.Windows.Forms.Application.DoEvents()。你试试在点击按钮后切换到另一个程序,再切换回来。如果没有加上这句,Winform会直到运行完毕才更新界面,加上这句切换回来时会继续显示进度条在前进。
      

  3.   

    建议使用BackgroundWorker,楼主可以查查MSDN,上面有很多例子
      

  4.   

    都是循环中更新的问题。Systems.DoEvents使用PeekMessage处理完消息队列,使UI有机会更新。WPF中你可以往Dispatch里PushFrame达到同样的效果
    public void DoEvents()
    {
        DispatcherFrame frame = new DispatcherFrame();
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
            new DispatcherOperationCallback(delegate(object f)
                {
                    ((DispatcherFrame)f).Continue = false;                return null;
                }
                ), frame);
        Dispatcher.PushFrame(frame);
    }
    在循环里调用一下DoEvents()就可以了Hope this helps
      

  5.   

    找到两篇比较有用的文章分享给大家:
    WPF学习与分享之二:DispatcherObject与WPF线程模型(上) http://www.cnblogs.com/Nullnoid/archive/2008/08/03/1259012.html
    WPF学习与分享之二:DispatcherObject与WPF线程模型(下) http://www.cnblogs.com/Nullnoid/archive/2008/08/06/1259429.html
    大致对Dispatcher有了些了解,DoEvents知道可以,但是由于调用这个方法后用户可以有短暂的时间操作UI不符合我们实际的要求。(我们需求是在做这件事的时候显示进度条,并且要保证用户不好对UI做任何操作,特别是ReSize)后来发现Dispatcher.CurrentDispatcher.Invoke 方法管用,把优先级调到Renderer, 这样主界面就不会响应用户操作,并且进度条能够更新了
    @zhouyongh 
    能对你的方法稍作解释下吗,BeginInvoke我知道是异步操作,传入一个frame是做什么, 谢谢!