【问题标题】:Pause a window like MessageBox.Show()暂停像 MessageBox.Show() 这样的窗口
【发布时间】:2017-10-10 20:03:42
【问题描述】:

我在 WPF 中实现了一种脚本语言,它允许用户编写多个并发操作的脚本。这些动作是使用 async/await 实现的,它们都在主线程上运行。

我现在在这个脚本语言中引入了一个步进调试器。目前,脚本引擎有一个窗口,而步进调试器则有一个不同的窗口。

我正在尝试在执行脚本操作之前在引擎窗口中停止进程,同时不阻止调试器窗口上的交互。 MessageBox.Show() 对此非常有用,尤其是因为它会暂停动画,而这些动画本身可能会在完成时开始新的操作。

Thread.Sleep() 当然根本不起作用,因为每个人都在主线程上。

C# 中是否有类似于 MessageBox.Show() 但没有 UI 的暂停机制?我试过调用 Dispatcher.DisableProcessing() ,我可以发誓我可以暂停引擎窗口,但现在我得到了错误:

'调度程序处理已暂停,但消息仍在处理中'

我认为理想情况下我想做这样的事情:

//Engine Window
private debugger;
void RunAction(ScriptAction action){
 if(action.BreakPoint){
  var pauserObject = PauseProcessesOnThisWindow();
  debugger.break(action, pauseObject);
}
}

//Debugger Window

void Continue_Click(){
 pauseObject.release();
}

如果我必须使用 MessageBox 方法,我可以看到从另一个窗口关闭它可能会很棘手,更不用说在调试器窗口中进行一些控制但仍然需要用户关闭它是一个尴尬的 UI引擎窗口中的框。

【问题讨论】:

  • 如果创建不可见窗口(大小为 1x1)并在其上调用 ShowDialog 会怎样?要释放,您只需设置该窗口的结果。
  • 有趣的想法 - 我会试一试。
  • 我试过 var win = new Window(); win.Owner = 引擎窗口; win.ShowDialog();它似乎阻止了与调试器和引擎窗口的交互。
  • @jchristof,看看this one,但请注意它仍然运行一个嵌套的消息循环,这会打开一整罐蠕虫(如here 中描述的重入问题)。至少你应该禁用 UI(ShowDialog 为此使用 EnableWindow API)。
  • 我发现你的问题很有趣。它远远高于我目前的知识水平,但如果它可以帮助可能与 Begin/EndModalMessageLoop 类似这个问题(关于表单,但有时有很多相似之处)entering-form-modal-message-loop-without-actual-form-showing跨度>

标签: c# wpf async-await dispatcher


【解决方案1】:

就我个人而言,我避免嵌套消息循环。由于可重入,它们非常危险。

我建议为您的脚本窗口使用专用线程(请参阅"Multiple Windows, Multiple Threads" in the WPF Threading Model documentation)。在单独的线程中运行单独的窗口在 WPF 上比在 WinForms 上要容易得多。

如果您确实想要一个嵌套的消息循环,您可以使用PushFrame 创建一个。

【讨论】:

  • 我认为这可能是门票,尤其是。因为我已经有一个脚本编辑器和控制台窗口,它们也与引擎窗口分开运行,但在主线程上。当引擎运行大量动画时,脚本编辑可能会很卡。我会仔细看看页面。谢谢!
  • 很好的参考 - 谢谢。我决定通过让每个等待“调试”任务等到 Timeout.Infinite 来制作停止进程的原型。调试器窗口最终可以取消该任务并允许它们全部继续。精度不像调用 wait(),但它可能足以满足我的需要并且不需要我生成新的 UI 线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多