Results 1 to 4 of 4

Thread: App Domains

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Question App Domains

    So I'm a bit new to the AppDomains but I have most of it figured out. I've managed to create a new AppDomain within a WPF Application in the Application_Startup event, which calls a method that executes another method in the new app domain. The method being executed in the new app domain is from a library that is NOT referenced in the project. I'm using reflection to load in the dll, create an instance of my class from the dll, and execute a method within that class instance which in turn loads up a new WPF window. What I want to do is when I hook into the closing event of the window, I want to invoke a method on the calling AppDomain to completly shutdown and unload the AppDomain that this form is running under the context of. I can't for the life of me seem to pass any delegate objects or an instance of the Application class into the the new AppDomain when creating the instance of the new class and calling the method. I keep getting an error that the class I'm passing in isn't marked as Serializable even though I do have the [Serialable] flag set. Right now when I close the form, the Application just keeps running in the background. The whole purpose to this is so that I can shutdown the AppDomain that the DLL is running under and be able to replace that DLL on the fly without it being in use by the application. Any assistance would be very much appreciated.

    Code:
           
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Windows;
    using System.IO;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Threading;
    using System.Reflection;
    using System.Security;
    using System.Security.Policy;
    using System.Windows.Threading;
    using System.Windows.Interop;
    using System.Runtime.InteropServices;
    using System.Windows.Media.Animation;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
    
    namespace NiRDs
    {
        public class RemoteSandbox<Tin, Tout> : MarshalByRefObject
        {
            public RemoteSandbox()
            {
            }
    
            public Tout Execute(Tin input, Func<Tin, Tout> method)
            {
                return method(input);
            }
    
            public override object InitializeLifetimeService()
            {
                return null;
            }
        }
    
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        [Serializable]
        public partial class NiRDsApp : Application
        {        
            static AppDomain NiRDsDomain = AppDomain.CreateDomain("NiRDsDomain");
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
                Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
    
                ExecuteInNewAppDomain(new object(), input =>
                {
                    Assembly NiRDsLibAssembly = Assembly.LoadFile(Environment.CurrentDirectory + @"\NiRDsLib.dll");
                    Type Nirds_StartupType = NiRDsLibAssembly.GetType("NiRDsLib.Nirds_Startup");
    
                    object NiRDs_StartupInstance = Activator.CreateInstance(Nirds_StartupType, null);
    
                    MethodInfo methodStartNiRDs = NiRDs_StartupInstance.GetType().GetMethod("StartNiRDs");
    
                    if (methodStartNiRDs != null)
                        methodStartNiRDs.Invoke(NiRDs_StartupInstance, null);
    
                    return input;
                }, NiRDsDomain);
            }
    
            public void ShutdownMethod()
            {
            }
    
            public static Tout ExecuteInNewAppDomain<Tin, Tout>(Tin input, Func<Tin, Tout> method, AppDomain Domain)
            {                        
                Type sandboxType = typeof(RemoteSandbox<Tin, Tout>);
    
                string sandboxAssemblyName = sandboxType.Assembly.GetName().Name;
                string sandboxTypeName = sandboxType.FullName;
    
                // Create a new sandbox
                RemoteSandbox<Tin, Tout> sandbox = (RemoteSandbox<Tin, Tout>)Domain.CreateInstanceAndUnwrap(sandboxAssemblyName, sandboxTypeName);
    
                return sandbox.Execute(input, method);
            }
    
        }
    }

  2. #2

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: App Domains

    I just added the following code to he method being executed when ExecuteInNewAppDomain is called and I get "Type 'NiRDs.NiRDsApp' in assembly 'NiRDs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=888b19f8a997884e' is not marked as serializable.". It doesn't want to let me assign to the delegate in the other class.

    EventInfo InvokeShutdown = NiRDs_StartupInstance.GetType().GetEvent("InvokeShutdown");
    Type tDelegateShutdown = InvokeShutdown.EventHandlerType;

    MethodInfo NiRDsShutdownMethod = this.GetType().GetMethod("ShutdownMethod");
    Delegate NiRDsShutdownDelegate = Delegate.CreateDelegate(tDelegateShutdown, this, NiRDsShutdownMethod);

    MethodInfo AddShutdownHandler = InvokeShutdown.GetAddMethod();
    AddShutdownHandler.Invoke(NiRDs_StartupInstance, new object[] { NiRDsShutdownDelegate });

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: App Domains

    I just got a bit further. I managed to hook into the event handler on the other library but I still can't get it to run on the new AppDomain. It's telling me that the method within the call to ExecuteInNewAppDomain is not marked as serializable. It works fine if I just execute this code directly without making a call to the ExecuteInNewAppDomain. I need to somehow mark this method as serializable.

    private void Application_Startup(object sender, StartupEventArgs e)
    {
    Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;

    MethodInfo NiRDsShutdownMethod = this.GetType().GetMethod("ShutdownMethod");

    //ExecuteInNewAppDomain(new object(), input =>
    //{
    Assembly NiRDsLibAssembly = Assembly.LoadFile(Environment.CurrentDirectory + @"\NiRDsLib.dll");
    Type Nirds_StartupType = NiRDsLibAssembly.GetType("NiRDsLib.Nirds_Startup");

    object NiRDs_StartupInstance = Activator.CreateInstance(Nirds_StartupType, null);

    MethodInfo methodStartNiRDs = NiRDs_StartupInstance.GetType().GetMethod("StartNiRDs");

    EventInfo EventInvokeShutdown = NiRDs_StartupInstance.GetType().GetEvent("InvokeShutdown");
    Type tDelegateInvokeShutdown = EventInvokeShutdown.EventHandlerType;

    Delegate NiRDsShutdownDelegate = Delegate.CreateDelegate(tDelegateInvokeShutdown, this, NiRDsShutdownMethod);

    MethodInfo AddShutdownHandler = EventInvokeShutdown.GetAddMethod();
    AddShutdownHandler.Invoke(NiRDs_StartupInstance, new object[] { NiRDsShutdownDelegate });

    if (methodStartNiRDs != null)
    methodStartNiRDs.Invoke(NiRDs_StartupInstance, null);

    // return input;
    //}, NiRDsDomain);
    }

    public void ShutdownMethod(object sender, EventArgs e)
    {
    MessageBox.Show("test");
    }

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Oct 2009
    Location
    Oshawa
    Posts
    214

    Re: App Domains

    Well, I found my answer. Once you load in the library into the new AppDomain there is no was to currently unload just that one AppDomain without unloading all of them.

    http://msdn.microsoft.com/en-us/libr...(v=vs.80).aspx

    I guess the best thing to do would be to check for updates when the application starts before loading in the DLL dynamically. Probably the only way I can do this without writing a seperate Update executable.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width