暂停类似MessageBox.Show()的窗口

问题描述:

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

I have a scripting language implemented in WPF that allows a user to script multiple concurrent actions. These actions are implemented using async/await and all of them run on the main thread.

我现在将步进调试器引入此脚本语言.当前,有一个与脚本引擎关联的窗口,以及与步骤调试器不同的窗口.

I'm now introducing a step debugger into this script language. Currently, there is one window associated with the script engine and a different window for the step debugger.

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

I'm trying to accomplish stopping processes in the engine window just before a scripted action executes while not blocking interactivity on the debugger window. MessageBox.Show() works great for this especially because it pauses animations which may themselves start new actions on completion.

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

Thread.Sleep() of course doesn't work at all because everyone is on the main thread.

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

Is there a pausing mechanism in C# similar to MessageBox.Show() but with no UI? I've tried calling Dispatcher.DisableProcessing() which I could have sworn worked to pause the engine window, but now I get the error:

分派器处理已暂停,但消息仍在处理中"

'Dispatcher processing has been suspended, but messages are still being processed'

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

I think ideally I'd like to do something like this:

//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,但是仍然需要用户关闭引擎窗口中的框.

If I have to go with the MessageBox approach, I can see that closing it from the other window can be tricky, not to mention that it's an awkward UI to have some control in the debugger window but still require the user to close the box from the engine window.

我个人避免嵌套消息循环.由于重新进入,它们非常危险.

Personally, I avoid nested message loops. They're considerably dangerous due to reentrancy.

我建议为您的脚本窗口使用专用线程(请参见多个Windows,多个线程" ).与WinForms相比,在WPF上在单独的线程中运行单独的窗口要容易得多.

I would recommend using a dedicated thread for your script window (see "Multiple Windows, Multiple Threads" in the WPF Threading Model documentation). Running a separate window in a separate thread is much easier on WPF than it ever was with WinForms.

但是,如果您确实希望嵌套消息循环,则可以使用

If you do want a nested message loop, though, you can create one using PushFrame.