PushFrame需要什么? [英] For what is PushFrame needed?

查看:102
本文介绍了PushFrame需要什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了 Dispatcher 对象的 PushFrame 方法。它是方法的简化版本:

I came across with PushFrame method of Dispatcher object. It is simplified version of method:

public void PushFrame(DispatcherFrame frame)
{
    // Stuff
    _frameDepth++;

    while(frame.Continue)
    {
        // Getting and dispatching messages
    }

    _frameDepth--;
    // Stuff
}

换句话说,它只是打开新的消息处理循环。但是我真的不明白这种方式的好处。 PushFrame 用于什么目的?有很好的用法示例吗?对于我来说,这种方法似乎不会导致明显的错误。

In other words it just opens new message processing loop. But I really cannot understand benefits of such way. For what purposes is PushFrame used? Is there good examples of its usage? As for me, It seems like that this method will lead to not obvious errors.

推荐答案

对于调度程序循环来说这是必不可少的在WPF程序中。 Windows上的每个GUI程序都有一个,它是生产者-消费者问题的通用解决方案。 OS和其他程序的产生地,WPF程序的UI线程在哪里使用。 GUI应用程序的一个严格要求,实现GUI的库代码绝不是线程安全的。您可以在这里轻松看到循环,看不到循环清空的线程安全队列,它是内置在操作系统中的。

It is essential plumbing for the dispatcher loop in a WPF program. Every GUI program on Windows has one, it is the universal solution to the producer-consumer problem. Where the OS and other programs produce and the UI thread of your WPF program consumes. A hard requirement for GUI apps, the library code that implements the GUI is never thread-safe. You can easily see the loop here, you cannot see the thread-safe queue that is emptied by the loop, it is built into the OS.

循环由以下项启动调用Application.Run()。在WPF应用程序中不容易看到,它在大多数应用程序中都是通过App.xaml文件自动生成的。这推动了第一个框架,只要您的应用程序停留在循环中,它就会一直运行。在事件处理程序上设置断点后,您将始终在调用堆栈调试器窗口中看到它。关闭应用程序的MainWindow是循环结束的正常方式。依次导致Run()方法返回,从而终止UI线程,从而终止进程。

The loop is started by a call to Application.Run(). Not easy to see in a WPF app, it is auto-generated in most apps from your App.xaml file. That pushes the first "frame", your app keeps running as long as it stays inside the loop. You'll always see it back in the Call Stack debugger window when you set a breakpoint on an event handler. Closing the MainWindow of your app is the normal way the loop ends. Which in turn causes the Run() method to return, which terminates the UI thread, which terminates the process.

在某些情况下,您希望使用嵌套的调度程序循环。一个模态循环。您每天使用的这种模态循环的一个例子是单击并在窗口角上拖动鼠标。现在,所有鼠标和键盘输入都会更改窗口的大小或位置,它们不再以常规方式用于操作UI。释放鼠标将终止该循环。这个调度程序循环是内置在操作系统中的,不是WPF完成的。

There are some scenarios where you like to have a nested dispatcher loop. A "modal loop". An example of such a modal loop that you use every day is when you click and drag the mouse on a window corner. All mouse and keyboard input now change the window size or location, they are no longer used to operate the UI in the normal way. Releasing the mouse terminates that loop. This dispatcher loop is built into the OS, it is not done by WPF.

但是WPF也可以用于这种模式循环。典范示例是 Window.ShowDialog()方法。在关闭对话框之前,该方法不会返回。由WPF再次在内部调用PushFrame()实现。只需通过调试器进行尝试,您就会在调用堆栈窗口中看到两个PushFrame调用。第一个是ShowDialog()调用的,第二个是Application.Run()调用的。如果您的对话框又显示一个对话框,您将获得更多。

But WPF has use for such a modal loop as well. The canonical example is the Window.ShowDialog() method. That method does not return until the dialog is closed. Achieved by WPF internally calling PushFrame() again. Just try it with the debugger, you'll see both PushFrame calls in the Call Stack window. The first one is the one that ShowDialog() called, the second one is the one that Application.Run() called. You'll get more if your dialog in turn displays a dialog.

一个不那么明显的示例是在UI线程上调用Dispatcher.Invoke()。在被调用的方法返回之前不会返回的方法。通常是一个bug,但是没有令人信服的理由禁止它。警告一词可能是适当的,模态循环非常危险。他们有引起重新进入错误的诀窍。导致DoEvents()方法臭名昭著的错误。 ShowDialog()禁用用户界面中所有其他窗口的主要原因。

A less obvious example is calling Dispatcher.Invoke() on the UI thread. A method that doesn't return until the invoked method returns. Normally a bit of a bug but there was no compelling reason to disallow it. A word of warning might be appropriate, modal loops are pretty dangerous. They have a knack for causing re-entrancy bugs. The kind of bug that made the DoEvents() method so notorious. A big reason why ShowDialog() disables all the other windows in your UI.

这篇关于PushFrame需要什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆