WPF LifeCyle в надстройке - PullRequest
       14

WPF LifeCyle в надстройке

3 голосов
/ 01 июня 2011

Я создал надстройку, которая вызывает через Reflection библиотеку классов WPF.Поскольку это библиотека классов, мне пришлось вручную создать экземпляр new System.Windows.Application().

. Затем конструктор класса (вызываемый с помощью отражения) создает окно и Show () (с Dispatcher.Run ().чтобы окно не закрывалось немедленно) или ShowDialog ().

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

При первом запуске (при создании экземпляра приложения) Application.Current.Dispatcher работает.

Но при втором запуске я обнаружилчто Application.Current.Dispatcher был остановлен.Я никогда не вызываю InvokeShutdown (), поэтому не понимаю, когда Диспетчер остановлен.

Когда я запускаю его второй раз, приложение уже запускается (это нормально), но Диспетчер остановлен.

Любая идея ?Спасибо!

Редактировать: В моей надстройке я пробовал 2 способа:

Первый способ:

        foreach (Type type in ass2_l.GetTypes())
        {
            if (type.Name == "Loader")
            {
                object obj_l = Activator.CreateInstance(type);
                BindingFlags bf_l = BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
                object[] argList_l = new object[1];
                argList_l[0] = "ok";
                type.InvokeMember("Load", bf_l, null, obj_l, argList_l);
            }
        }

Когда я вызываю dll напрямую из надстройки, Application.Current.Dispatcher находится в фоновом состоянии с именем «VSTA_Main».Когда я запускаю второй раз, Dispatcher все еще находится в фоновом состоянии.

Второй способ:

        t_m = new Thread(loadDll);
        t_m.SetApartmentState(ApartmentState.STA);
        t_m.Start();

На самом деле loadDll содержит тот же код «первого пути»код.Когда я запускаю эту часть в первый раз, Диспетчер работает, и все совершенно нормально.При повторном запуске Dispatcher останавливается.

EDIT 2: Проблема заключается во втором способе.Когда loadDll завершается, а затем я снова нажимаю на кнопку надстройки, t_m останавливается, и создание другого не решает проблему, так как Dispatcher ManagedThreadId имеет старый t_m ManagerThreadId: /

EDIT3: Проблема определенно не вызвана надстройкой.Если вы просто создаете программу, которая запускает поток каждый раз, когда вы нажимаете на кнопку.Поток пытается создать библиотеку классов DLL WPF (по отражению), и если вы нажмете второй раз на эту кнопку (вызов другого потока), так как Dispatcher все еще "связан" со старым потоком, Dispatcher будет "остановлен"(как старая нить)

Ответы [ 2 ]

7 голосов
/ 01 июня 2011

В обработчик событий ThisAddin.Startup поместите этот код:

private void ThisAddInStartup(object sender, EventArgs e)
{
    if (System.Windows.Application.Current == null)
        new System.Windows.Application();
    System.Windows.Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown
}

Это должно с этим разобраться, в прошлом у меня все работало нормально.

1 голос
/ 03 июня 2011

Наконец, я решил проблему, используя бесконечный цикл, чтобы сохранить поток в рабочем состоянии, с помощью AutoResetEvent / ManualResetEvent, чтобы запустить / остановить поток ...

Поскольку поток никогда не заканчивается (и вызывает методкоторый загружает dll WPF UI при получении события запуска), мы никогда не останавливаем поток (пока не остановим надстройку), и диспетчер никогда не останавливается тоже.

Кстати, спасибо за все вашиответы:)

...