Wpf中Dispatcher.Invoke和Dispatcher.BeginInvoke的区别
看下面的代码:
1 2 3 4 5 6 7 8 9 10 | new Thread(()=> { Application.Current.Dispatcher.BeginInvoke( new Action(() => { while ( true ) { Thread.Sleep(1000); } }), null ); Console.WriteLine( "test" ); }).Start(); |
这段代码,会在控制台打印test,然后界面会一直卡住。界面卡住,说明while循环是在ui线程执行的,能够打印test,说明在执行Application.Current.Dispatcher.BeginInvoke时并没有阻塞当前界面,如果把BeginInvoke改成Invoke,那么test将不会被打印,说明Invoke方法的逻辑是把委托交给ui线程执行,并阻塞当前线程,直到委托结束。而BeginInvoke方法则首先新开一个线程,那新开的线程,再将委托交给ui线程处理。注意,最终执行委托的线程都是ui线程。所以,BeginInvoke由于有个新开线程的过程,不会阻塞当前线程。但仍然会阻塞界面。
另外BeginInvoke是可以指定优先级的,通过方法BeginInvoke(DispatcherPriority, Delegate)来设置优先级。
//------------------------------------------------------------------------------------------------------------------
UI卡顿假死问题 转载于:https://www.cnblogs.com/YYkun/p/10782653.html
误区1:使用不同的线程操作UI控件和耗时操作(即,跨线程操作UI控件CheckForIllegalCrossThreadCalls =
false
;
),
注意:此处只是为了记录......
原始同步操作如下所示:
1 2 3 4 5 6 7 8 | private void button1_Click( object sender, EventArgs e) { Waintting waitting = new Waintting(); waitting.Show(); Thread.Sleep(5000); //模拟等待 MessageBox.Show( "连接数据库成功" , "信息" , MessageBoxButtons.OK, MessageBoxIcon.Information); waitting.BeginInvoke((Action)waitting.Close); //BeginInvoke方法返回UI线程更新UI界面控件的机制。 } |
1 2 3 4 5 6 7 8 9 10 11 12 | private void btnWatting_Click( object sender, EventArgs e) { Waintting waitting = new Waintting(); waitting.Show(); Task.Factory.StartNew(() => // 将阻塞线程的操作在另外一个线程中执行,这样就不会堵塞UI线程。 { Thread.Sleep(5000); //模拟等待 MessageBox.Show( "连接数据库成功" , "信息" , MessageBoxButtons.OK, MessageBoxIcon.Information); waitting.BeginInvoke((Action)waitting.Close); //BeginInvoke方法返回UI线程更新UI界面控件的机制。 }); } |
调整后异步方式如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | private void WattingTest2_Click( object sender, EventArgs e) { Func< string > wait = () => { Thread.Sleep(5000); //模拟耗时操作,例如数据库操作等 return "abc" ; }; wait.BeginInvoke( new AsyncCallback(result => { string rst = wait.EndInvoke(result); this .Invoke((Action)(() => this .textBox1.AppendText(rst))); }), null ); } |
// 盲区--------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 | this .progressBar1.Dispatcher.BeginInvoke((ThreadStart) delegate { this .progressBar1.Value = 10); }); Dispatcher.BeginInvoke( new Action( delegate { this .progressBar1.Value = 10); })); Dispatcher.Invoke((Action)(() => this .progressBar1.Value = 10); )); |
本文作者:浅绿色i
本文链接:https://www.cnblogs.com/xfweb/p/15975365.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步