WPF vs WinForm 多线程UI跟新问题
写了个小小的测试程序,在Winform分别加了一个Winform的ProcessBar和WPF的ProcessBar,再加一个button, 下面是button Click事件的代码:
C# code
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下的线程除外)
------解决方案--------------------...
------解决方案--------------------
wpf下的多线程写法确实跟winform下的不一样,我当初平移winform下的时候就遇到过这个问题.
不过说实在的,具体什么原因我不是很懂,毕竟是做bs出身的,不过后来一个同事用一个叫什么dispatcher(名字可能有误)的东西实现了.
楼主可以用那个方法试一试,希望能帮到你.
------解决方案--------------------
不管是Winform还是WPF都应该加上System.Windows.Forms.Application.DoEvents()。
你试试在点击按钮后切换到另一个程序,再切换回来。如果没有加上这句,Winform会直到运行完毕才更新界面,加上这句切换回来时会继续显示进度条在前进。
------解决方案--------------------mark
------解决方案--------------------建议使用BackgroundWorker,楼主可以查查MSDN,上面有很多例子
------解决方案--------------------
都是循环中更新的问题。
Systems.DoEvents使用PeekMessage处理完消息队列,使UI有机会更新。
WPF中你可以往Dispatch里PushFrame达到同样的效果
C# code
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);
}