tags:

views:

25

answers:

1

I want to launch a WPF App, in a 2nd AppDomain, from a 'loader' class. If the WPF App times itself out, I want it to fire an event back to the loader class and the loader class will Unload() the the 2nd AppDomain and show a login screen. If the user logs back in, the same process will repeat.

I have this working to a degree by :

  1. Loader class creates the 2nd AppDomain and class B in that domain via CreateInstanceAndUnwrap.

  2. Loader class creates a MarshalByRefObject that has a Timeout event, and passes it to a B.StartUp(MBRO), which passes the MBRO on to the constructor of the WPF App(). Loader class adds a handler to MBRO.Timeout.

  3. WPF App times out, calls MBRO.Timeout, which is handled by the Loader class. In the event handler, Loader class shuts down B WPF App and shows the login window.

The problem is that I can't Unload the 2nd AppDomain in step 3. When I do it, it shuts down the host appdomain as well (no exceptions or anything, the whole thing shuts down).

I think the problem happens because the event handler delegate is being fired by the WPF App which is in the 2nd domain, and therefore I am trying to pull the rug from under App Domain from within a delegate it has fired.

Is this correct? Does it work like this across Domains?

In summary, can anyone suggest a way where you can launch a 2nd AppDomain, receive an event from the 2nd AppDomain and Unload() the 2nd AppDomain upon receiving that event? I think I need someone to decouple the receipt of the event from the act of Unloading the app domain.

A: 

Yes, this is correct. The problem is that the stack trace passes from the primary domain through the second domain and back to the primary domain.

You have a few choices here.

  1. You call into the app domain. If you could make it so that the method you call returns with a specific status code (e.g. Success or Timeout), you don't have the stack problem anymore;

  2. You call the app domain from a second thread:

    1. From the first thread, create a new thread which creates the app domain and starts the application;

    2. Still in the first thread, create a AutoResetEvent and do a WaitOne() on that;

    3. When the event is executed from the app domain, it will not execute on the first thread. I'm not sure whether the event will execute on the second event and if not, creating the secondary thread will not be necessary. From the thread the comes in on, set a 'Timeout' flag somewhere and do a Set() on the event;

    4. The primary thread wakes up and knows what to do depending on the status of the flag.

Pieter