为何Dispatcher.InvokeAsync先弹22222消息框?换Invoke则顺序正常
问题代码
this.Dispatcher.InvokeAsync( () => { MessageBoxResult result = MessageBox.Show("111111111111111111111111", "Child process failed", MessageBoxButton.OK); } ); this.Dispatcher.InvokeAsync( () => { MessageBoxResult result = MessageBox.Show("22222222222222222222222", "Child process failed", MessageBoxButton.OK); } );
为什么InvokeAsync会导致消息框顺序颠倒?
核心原因是InvokeAsync的异步特性和MessageBox.Show的模态消息循环机制:
InvokeAsync是异步调用,它只负责把委托加入UI线程的Dispatcher消息队列,然后立即返回,不会等待委托执行完成。所以代码会先将弹出"111..."的委托加入队列,紧接着把弹出"222..."的委托也加入队列,队列顺序本身是111委托 → 222委托。- 当UI线程开始处理
111委托时,执行到MessageBox.Show会弹出模态对话框。模态对话框会启动自己的独立消息循环来处理用户交互,而这个循环并不会阻塞Dispatcher队列的后续处理——它会继续取出队列中的222委托执行,导致"222..."的消息框先显示在"111..."的上方(模态窗口层级更高),看起来就像是先弹出了"222"。
为什么换成Invoke就恢复正常?
Dispatcher.Invoke是同步调用:
- 第一个
Invoke会阻塞当前线程,直到UI线程完全执行完111委托(也就是你关闭"111"的消息框),才会继续执行代码中的第二个Invoke。 - 第二个
Invoke同样会阻塞当前线程,直到222委托执行完成。这种同步等待的机制严格保证了消息框的弹出顺序,先"111"后"222"。
内容的提问来源于stack exchange,提问作者yunate
相关产品推荐
相关产品推荐

