VSTO WPF Outlook Addin - не отвечающий пользовательский интерфейс в случайных случаях - PullRequest
2 голосов
/ 23 ноября 2011

У нас есть надстройка VSTO для Outlook 2007, разработанная с использованием .Net 4.0 WPF.Один из ПК, на котором он был развернут, имеет проблему с пользовательским интерфейсом.В некоторых случаях пользовательский интерфейс перестает отвечать на запросы на несколько мгновений.Клики не работает.Через несколько секунд все приходит в норму, и пользователь может нажимать кнопки.Другие надстройки, установленные на ПК, - SnagIT и панель инструментов Google Desktop Outlook.

Пожалуйста, помогите нам, если у вас есть какие-либо комментарии по этому вопросу.

Ответы [ 2 ]

2 голосов
/ 12 декабря 2013

У меня была такая же проблема с надстройкой Word - на очень громоздкой коробке разработчика - пользовательский интерфейс просто зависал, хотя я выполнял всю свою работу в фоновом режиме.

Моя теорияв том, что Word работал над потоком пользовательского интерфейса, хотя я вызывал его из фоновых потоков и т. д.

Я попытался провести эксперимент - создать экземпляр объекта Window в новом потоке (т. е. чтобы мой поток пользовательского интерфейса былне то же самое, что рабочий поток Word) - и это сработало.Мой пользовательский интерфейс больше не блокируется через случайные интервалы.

Будьте осторожны, чтобы избавиться от любых экземпляров объектов COM, прежде чем ваш поток закроется, и особенно остерегайтесь доступа к COM между потоками (возможно, с помощью Dispatcher.Invoke обратно кПоток приложения хоста Office при доступе к любому из его RCW ... - Диспетчеры связаны с потоками, в которых они создаются, поэтому вам просто нужно создать экземпляр диспетчера в обратном вызове приложения хоста офиса и т. Д ...)

Примечание: Если вы Dispatcher.Invoke вернетесь к вызывающему потоку, вы не сможете использовать Thread.Join, как показано ниже.(В этом случае вам нужно будет обрабатывать события приложения, Thread.Sleep и Thread.Yield) в занятом цикле.В противном случае вы получите тупик.

Вот пример обобщенной версии того, что я делаю:

// This approach makes WPF Windows an order of magnitude more responsive
Thread t = new Thread(() =>
{
    try
    {
        // Implement the IDisposable pattern on your window to release
        //   any resources before the thread exits
        using (var myWindow = new MyWindow())
        {
            // Do any other pre-display initialization with the myWindow
            //   object here...

            myWindow.ShowDialog();
        }
    }
    finally
    {
        // Strongly Recommended (not doing this may cause
        //   weird exceptions at application shutdown):
        Dispatcher.CurrentDispatcher.InvokeShutdown();
    }
});

t.SetApartmentState(ApartmentState.STA); // Required
t.IsBackground = false; // Recommended

t.Start(); // Kicks off the new UI thread
t.Join();  // Blocks execution until the new UI thread has finished executing...
0 голосов
/ 28 ноября 2011

Похоже, вы выполняете работу в потоке пользовательского интерфейса, который останавливает пользовательский интерфейс до тех пор, пока задача не будет завершена.Вы должны использовать библиотеку Tasks для выполнения работы, не связанной с пользовательским интерфейсом.Если вы выполняете работу, используя Task, который требует обновления пользовательского интерфейса, вам необходимо использовать WPF Dispatcher.

...