开发者

WPF LifeCyle in an Add-in

I've created an add-in, which call via Reflection, a WPF Class Library. Since this is a class library, I had to instanciate manually a new System.Windows.Application().

Then, the class constructor (the one called via reflection) create a window, and Show() (with Dispatcher.Run() to avoid the window to close immediately) or ShowDialog().

Since my application is into an add-in, Application is still alive. Therefore, I can instanciate this only once.

On the first launch 开发者_如何学运维(when Application is instanciated), the Application.Current.Dispatcher is Running.

But on the second launch, I firured out that the Application.Current.Dispatcher was Stopped. I never call InvokeShutdown() so I don't understand when the Dispatcher is stopped.

When I launch this a second time, Application is already instanciated (it's normal) but Dispatcher stopped.

Any idea ? Thanks !

Edit : In my Add-in, I've tried 2 ways :

First way :

        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);
            }
        }

When I call directly the dll from the add-in, Application.Current.Dispatcher is in Background State, with name "VSTA_Main". When I launch a second time, Dispatcher is still in background state.

Second way :

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

loadDll actually contain the same code of the "first way" code. When I launch this part for the first time, the Dispatcher is Running, and all is perfectly normal. When launched the second time, Dispatcher is stopped.

EDIT 2 : The problem is in the second way. When loadDll is finished and then I click again on my add-in button, t_m is stopped and creating another one don't resolve the problem since the Dispatcher ManagedThreadId has the old t_m ManagerThreadId :/

EDIT 3 : The problem is definately not caused by the Add-in. If you Just create a program that launch a thread everytime you click on a button. The thread try to instanciate a DLL WPF Class Library (by reflection), and if you click a second time on this button (calling another thread), as the Dispatcher is still "linked" to the old thread, the Dispatcher is "stopped" (like the old thread)


In ThisAddin.Startup event handler put this code:

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

That should sort it out, it has worked fine for me in the past..


Finally, I solved the problem using an infinite loop to stay the thread in running state, with AutoResetEvent / ManualResetEvent to start/stop the thread...

As the thread never finish (and call a method which load the WPF UI dll when he receive the start event), we never stop the thread (until we stop the Add-in), and the dispatcher is never stopped too.

BTW, thank you for all your answers :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜