Application.Current.Shutdown() 与 Application.Current.Dispatcher.BeginInvokeShutdown()

发布于 2024-09-04 01:14:29 字数 475 浏览 7 评论 0原文

首先介绍一些背景知识:我有一个 WPF 应用程序,它是旧版 Win32 应用程序的 GUI 前端。旧版应用程序作为 DLL 在单独的线程中运行。用户在 UI 中选择的命令将在该“旧线程”上调用。

如果“旧线程”完成,GUI 前端将无法再执行任何有用的操作,因此我需要关闭 WPF 应用程序。因此,在线程方法的末尾,我调用 Application.Current.Shutdown()

由于我不在主线程上,因此我需要调用此命令。然而,后来我注意到调度程序也有 BeginInvokeShutdown() 来关闭调度程序。 有什么区别

Application.Current.Shutdown();

所以我的问题是:调用和调用

Application.Current.Dispatcher.BeginInvokeShutdown();

First a bit of background: I have a WPF application, which is a GUI-front-end to a legacy Win32-application. The legacy app runs as DLL in a separate thread. The commands the user chooses in the UI are invoked on that "legacy thread".

If the "legacy thread" finishes, the GUI-front-end cannot do anything useful anymore, so I need to shutdown the WPF-application. Therefore, at the end of the thread's method, I call Application.Current.Shutdown().

Since I am not on the main thread, I need to invoke this command. However, then I noticed that the Dispatcher also has BeginInvokeShutdown() to shutdown the dispatcher. So my question is: What is the difference between invoking

Application.Current.Shutdown();

and calling

Application.Current.Dispatcher.BeginInvokeShutdown();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

誰ツ都不明白 2024-09-11 01:14:29

我做了一些更多的测试,现在我想我知道了差异:

1) 正如 MSDN 页面中所述,BeginInvokeShutdown 除了关闭 Dispatcher 之外,还清除/中止其队列。 Shutdown 首先处理 Dispatcher 队列中的所有项目。

关闭过程开始后,队列中所有待处理的工作项都会中止。

2)在应用程序中,我可以处理 Application.Exit< /a> 事件。当我调用 Shutdown 时会触发此事件,但当我调用 BeginInvokeShutdown 时不会触发此事件!这同样适用于 Window.Closing 和 < a href="http://msdn.microsoft.com/en-us/library/system.windows.window.lined.aspx" rel="noreferrer">Window.Closed。

至于相似之处,这两种情况都会退出主线程。根据其他正在运行的线程,这也会关闭进程:非后台线程在进程退出之前运行完成。

下面是我的测试代码。注释 Application_Startup 中的一个或另一个方法调用:

public partial class App
{
    private void Application_Exit(object sender, ExitEventArgs e)
    {
        MessageBox.Show("Exiting");
    }

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var testThread = new Thread(
            () =>
            {
                Thread.Sleep(2000);
                Application.Current.Dispatcher.BeginInvokeShutdown(System.Windows.Threading.DispatcherPriority.Send);
                //Application.Current.Dispatcher.BeginInvoke(new Action(() => Application.Current.Shutdown()));
            });
        testThread.Start();
    }
}

public partial class Window1
{
    public Window1()
    {
        this.InitializeComponent();

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("One");
        }));

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("Two");
        }));

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("Three");
        }));

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("Four");
        }));
    }

    private void Window_Closed(object sender, EventArgs e)
    {
        Console.WriteLine("Closed");
    }

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        Console.WriteLine("Closing");
    }
}

I did some more testing, and now I think I know the differences:

1) As stated in the MSDN page, BeginInvokeShutdown, besides shutting down the Dispatcher, also clears/aborts its queue. Shutdown first handles all items in the Dispatcher queue.

Once the shutdown process begins, all pending work items in the queue are aborted.

2) In an application I can handle the Application.Exit event. This event is fired when I call Shutdown, but NOT fired when I call BeginInvokeShutdown! The same applies to Window.Closing and Window.Closed.

As for similarities, in both cases the main thread is exited. Depending on other running threads, this also shuts down the process: non-background threads are run to completion before the process exits.

Below is my test code. Comment one or the other method call in Application_Startup:

public partial class App
{
    private void Application_Exit(object sender, ExitEventArgs e)
    {
        MessageBox.Show("Exiting");
    }

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var testThread = new Thread(
            () =>
            {
                Thread.Sleep(2000);
                Application.Current.Dispatcher.BeginInvokeShutdown(System.Windows.Threading.DispatcherPriority.Send);
                //Application.Current.Dispatcher.BeginInvoke(new Action(() => Application.Current.Shutdown()));
            });
        testThread.Start();
    }
}

public partial class Window1
{
    public Window1()
    {
        this.InitializeComponent();

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("One");
        }));

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("Two");
        }));

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("Three");
        }));

        Dispatcher.BeginInvoke(new Action(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("Four");
        }));
    }

    private void Window_Closed(object sender, EventArgs e)
    {
        Console.WriteLine("Closed");
    }

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        Console.WriteLine("Closing");
    }
}
两仪 2024-09-11 01:14:29

Shutdown() 的 MSDN 页面
BeginInvokeShutdown() 的 MSDN 页面

看来这只是术语的碰撞。 BeginInvokeShutdown 关闭该调度程序,理论上您的应用程序可以在之后继续运行(尽管没有调度程序,它的作用会非常有限)。然而,Shutdown 实际上会退出您的应用程序,这正是您想要的。

MSDN page for Shutdown()
MSDN page for BeginInvokeShutdown()

It seems that this is just a collision of terminology. BeginInvokeShutdown shuts down that dispatcher, your application can in theory continue to live afterwards (though without a dispatcher, it'd be pretty limited). Shutdown however actually exits your application, which is what you want.

一曲琵琶半遮面シ 2024-09-11 01:14:29

顺便说一句,丹尼尔 - 我们的应用程序是以相同的方式构建的 - WPF 前端到单独运行的 Win32 COM (Delphi) 应用程序。讨论和比较我们的方法会很有趣。

但为什么我偶然发现你的问题是因为我们的应用程序过去常常调用 Dispatcher.BeginInvokeShutdown,它工作得很好,除了少数情况下它没有正确终止。当我最终拿到一台可以重现此问题的机器时,切换到 Application.Current.Shutdown() 解决了问题。我还是不明白出了什么问题。

By the way, Daniel - our application is built in the same way - WPF front-end to a Win32 COM (Delphi) application running separately. It would be interesting to talk and compare our approaches.

But why I have stumbled upon your question is that our application used to call Dispatcher.BeginInvokeShutdown, which worked fine with exception of a few cases where it did not terminate properly. When I finally got my hands on a machine on which this was reproducible, switching to Application.Current.Shutdown() fixed the problem. I still do not understand what was the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文