Nano Hash - криптовалюты, майнинг, программирование

Почему закрытие диалогового окна WPF с дочерним элементом зависает надстройкой VSTO?

Рассмотрим следующий код (создайте пустую надстройку VSTO Word 2010 и вставьте ее):

using System.Diagnostics;
using System.Windows;
using System.Windows.Interop;
using Action = System.Action;

namespace WordAddIn1HangTest
{
    public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Window window1 = new Window();
            window1.Content = "1";
            Window window2 = new Window();
            window2.Content = "2";
            WindowInteropHelper windowInteropHelper1 = new WindowInteropHelper(window1);
            WindowInteropHelper windowInteropHelper2 = new WindowInteropHelper(window2);

            System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                windowInteropHelper1.Owner = Process.GetCurrentProcess().MainWindowHandle;
                window1.ShowDialog();
                MessageBox.Show("Hello");
            }));

            System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                windowInteropHelper2.Owner = windowInteropHelper1.Handle;
                window2.ShowDialog();
            }));

            System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                window1.Close();
            }));
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion
    }
}

Он закрывает модальный диалог, у которого вместо этого есть другой модальный дочерний элемент. Я знаю, что это не обычное поведение, но я не нашел ничего, говорящего о том, что это ошибка, и на самом деле это работает в приложении WPF, оно зависает только в надстройке VSTO.

Поскольку мы закрываем окно1, мы должны увидеть приветственное сообщение, которое никогда не приходит.

Должен ли я заполнить Microsoft ошибку?

11.01.2018

  • Вы уверены, что System.Windows.Threading.Dispatcher должен работать в среде Office? Разве пространство имен System.Windows не для приложений WPF? 11.01.2018
  • Я думаю, что проблема не связана с Dispatcher, я почти уверен, что это происходит с любым другим типом Invoke, который вы используете. Завтра проверю, сейчас я Афк. 11.01.2018
  • Во всяком случае, я использую окна Wpf здесь. Мы разрабатываем надстройку Wpf. 11.01.2018

Ответы:


1

Непонятно, чего вы пытаетесь добиться, вызывая метод BeginInvoke — вызов его из основного потока в целом не всегда является хорошей идеей. Если вы замените его на Invoke, код будет работать нормально. И поскольку вы уже находитесь в основном потоке, вам вообще не нужен диспетчер — вы можете просто вызвать свой код прямо оттуда. Кроме того, я не понимаю цели взлома с модальными окнами. Идея модальных окон заключается в том, что родительские окна заморожены и неизменны (в том числе закрываются), пока модальное окно открыто. Так что это может привести к странным результатам даже в традиционной программе WinForms, а VSTO гораздо более взрывоопасен. Вот несколько советов, как избежать проблем с окнами в VSTO.

  • Работа с диспетчером потоков в VSTO отличается от работы с приложением winform. Он имеет множество ошибок или, возможно, неожиданное поведение. Вы должны сохранить исходный экземпляр System.Windows.Threading.Dispatcher.CurrentDispatcher, который у вас есть как текущий во время запуска, а затем вызвать этот диспетчер во время выполнения, а не Current. В противном случае вы не сможете безопасно вызывать методы в основном потоке из фоновых потоков.
  • Вы можете показывать только модальные диалоги, только из основного потока. Немодальные окна вызывают странное поведение при закрытии Word (это зависит от версии Word). Если вам нужно показать немодальное окно, вы можете использовать панели задач VSTO, если вы можете встроить WPF в панель задач.
11.01.2018
  • Суть конечно в том, чтобы показать баг, реальный код другой и в нашем коде это вызвано состоянием гонки, которое зависает весь ворд. Задокументированы ли где-нибудь ошибки Dispatcher, чтобы я мог полностью понять проблемы? Спасибо за все! 11.01.2018
  • @IgnacioSolerGarcia Нет, ошибки не документированы и имеют небольшие различия между версиями Office. Я все еще не понимаю вашу точку зрения. пример весьма далек от реальной жизни. 12.01.2018
  • Я знаю пример, это немного странно, но дело в том, что нечто подобное произошло в нашем коде из-за ошибки, вызванной состоянием гонки. Этот код имитирует состояние гонки при закрытии окна1 перед закрытием окна2. Поскольку нигде не задокументировано, что это могло зависнуть Word, вопрос в том, является ли это ошибкой в ​​​​модуле VSTO и должен ли я заполнить ее для команды Microsoft? 12.01.2018
  • @IgnacioSolerGarcia Я думаю, закрывая родительское окно модального диалога, вы делаете что-то совершенно неправильное. Вы пробовали этот код в WinForms? Что касается ошибок Office - Microsoft не предоставляет возможности сообщать об ошибках, и, как правило, они никогда их не исправляют. 12.01.2018
  • Я просто попробовал это из любопытства, и Windows Forms обрабатывает это по-другому, но правильно. Когда вы вызываете window1.Close(), ничего не происходит, но когда вы закрываете window2, window1 также закрывается. 12.01.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..