Приложение. Текущий. Завершение работы () по сравнению с приложением. Текущий. Диспетчер. BeginInvokeShutdown ()

Сначала немного фона: у Меня есть приложение WPF, которое является фронтендом GUI к приложению Win32 прежней версии. Выполнение приложения прежней версии как DLL в отдельном потоке. Команды, которые пользователь выбирает в UI, вызываются на тот "поток прежней версии".

Если "поток прежней версии" концы, фронтенд GUI не может больше делать ничего полезного, таким образом, я должен завершить работу WPF-приложения. Поэтому в конце метода потока, я звоню Application.Current.Shutdown().

Так как я не нахожусь на основном потоке, я должен вызвать эту команду. Однако затем я заметил, что Диспетчер также имеет BeginInvokeShutdown() завершать работу диспетчера. Таким образом, мой вопрос: Каково различие между вызовом

Application.Current.Shutdown();

и вызов

Application.Current.Dispatcher.BeginInvokeShutdown();
8
задан Daniel Rose 28 May 2010 в 09:37
поделиться

2 ответа

Я провел еще несколько тестов, и теперь я думаю, что знаю различия:

1) Как указано на странице MSDN, BeginInvokeShutdown , помимо завершения работы Диспетчера , также очищает / прерывает свою очередь. Завершение работы сначала обрабатывает все элементы в очереди диспетчера.

Как только начинается процесс завершения работы, все незавершенные рабочие элементы в очереди прерываются.

2) В приложении я могу обработать событие Application.Exit . Это событие запускается, когда я вызываю Shutdown, но НЕ запускается, когда я вызываю BeginInvokeShutdown! То же самое относится к Window.Closing и 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");
    }
}
9
ответ дан 5 December 2019 в 17:35
поделиться

Страница MSDN для Shutdown()
Страница MSDN для BeginInvokeShutdown()

Похоже, что это просто столкновение терминологии. BeginInvokeShutdown отключает диспетчер, ваше приложение теоретически может продолжать жить после этого (хотя без диспетчера это будет довольно ограничено). Shutdown, однако, фактически завершает работу приложения, что вам и нужно.

1
ответ дан 5 December 2019 в 17:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: