WPF: Как совершать вызовы Dispatcher.Вызвать () синхронно?

#wpf #asynchronous #mvvm #wix #bootstrapper

#wpf #асинхронный #mvvm #wix #загрузчик

Вопрос:

В моем приложении начальной загрузки Wix, управляемом на основе MVVM, при обработке различных событий я пытаюсь показать пользователю представление, чтобы получить некоторый ввод. Похоже, что события записи выполняются асинхронно, потому что используется Dispatcher.Invoke() , он пропускает или проходит мимо представления и попадает в последнее событие, т.е. Не дожидается завершения этой задачи ввода.

Вот обработчик события, который необходимо завершить, прежде чем нажимать на последний:

Пожалуйста, обратите внимание, что когда MessageBox.Show выскакивает, он ждет, пока мы его не закроем. Во время отладки я вижу, что он фактически переключился на MissingSourceView и загрузил MissingSourceViewModel, но затем, пропуская его, и выполняет ApplyComplete();

 BootstrapperApplication.ResolveSource  = (sender, e) => {
                        System.Windows.Forms.MessageBox.Show("Inside ResolveSource");

                     WixBootstrapperData.CurrentDispatcher.Invoke(((Action)(() =>
                        {
                            WixBootstrapperData.CurrentViewModel = new MissingSourceViewModel(WixBootstrapperData, InfoMessage);
                        })));
                    };


BootstrapperApplication.ApplyComplete  = (sender, e) =>
            {               
                WixBootstrapperData.BootstrapperApplicationModel.FinalResult = e.Status;
                WixBootstrapperData.CurrentDispatcher.Invoke((Action)(() =>
                {
                  InfoMessage = AppResource.MsgFinished;
                  WixBootstrapperData.CurrentViewModel = new FinishViewModel(WixBootstrapperData, InfoMessage);
                }
                ));
            };
  

Я думаю, я должен использовать await и async с ResolveSource(), но я сталкиваюсь с такими ошибками, как:

Ошибка CS1061 ‘BaseViewModel’ не содержит определения для ‘GetAwaiter’, и не удалось найти метод расширения ‘GetAwaiter’, принимающий первый аргумент типа ‘Task’ (вам не хватает директивы using или ссылки на сборку?)

Есть идеи, как заставить его ждать завершения внутри ResolveSource(), а затем перейти туда, куда он хочет?

Комментарии:

1. Вы можете выбрать механизм синхронизации вручную, такой как событие сброса: msdn.microsoft.com/en-us/library /…

Ответ №1:

Используйте это и, пожалуйста, сообщите, решает ли это вашу проблему.

         WixBootstrapperData.CurrentDispatcher.Invoke(((Action)(() =>
        {
           Task.Factory.StartNew(() => {
              WixBootstrapperData.CurrentViewModel = new MissingSourceViewModel(WixBootstrapperData, InfoMessage);
           }).RunSynchronously();
        })));
  

Комментарии:

1. сбой со следующим исключением: System. Исключение InvalidOperationException: запуск синхронно не может быть вызван для задачи, которая уже была запущена.

2. CurrentDispatcher является запущенным диспетчером, и вызов запускает другую операцию в том же потоке диспетчера..

3. Исключение: необработанное исключение типа ‘System. Исключение InvalidOperationException’ произошло в mscorlib.dll Дополнительная информация: RunSynchronously не может быть вызван для задачи, которая уже была запущена.