Unloading an Assembly

Hello,
I read in one of the Blogs that an Assembly cannot be unloaded. It has to be loaded into a AppDomain and then unloaded. I have tried that.

Take a look at the following code.

AppDomain newDomain = AppDomain.CreateDomain("NewDomain");
Assembly myAssembly =
newDomain.Load(AssemblyName.GetAssemblyName(assemblyPath);
After doing Reflection on myAssembly, I used

AppDomain.Unload(newDomain);

There are a some other statements in the CurrentDomain.

While executing, Iam getting the following exception:

'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll

Additional information: Insufficient state to deserialize the object. More information is needed.

Are there any Remoting issues I see that term in the Stack Trace.
What went wrong Please tell me.


Answer this question

Unloading an Assembly

  • TheGunShow

    Hi Blair,

            I just used the two statements that I gave. Creation of AppDomain and  Loading  the  assembly.  Afterwards unloaded it. I didn't use any create instance statements. Is anything else necessary Is any kind of Remoting necessary After unloading, Iam again modifying the assembly. For this Iam using a differenct package - Mono. If I don't unload it then there is an exception that the assembly is already in use.


             Thank you.

  • tech2hardikjoshi

    Hi,

    I didn't get you. Iam giving an .exe file for filename1. Like SampleApplication.exe. So it should die. But I feel that Iam missing something in the inter domain communication part

    How should I resolve it



  • phenshaw

    what line generates the error

    Assembly myAssembly = newDomain.Load(AssemblyName.GetAssemblyName(filename1));

    or

    AppDomain.Unload(newDomain);

    or. . . is it in the for loop

    this works for me:

    AppDomain dynDomain = AppDomain.CreateDomain("Dynamic Domain");
    System.Reflection.
    Assembly theAssembly = dynDomain.Load(
                System.Reflection.
    AssemblyName.GetAssemblyName("WindowsApplication1.exe"));
    Type[] types = theAssembly.GetTypes();
    foreach (Type t in types)
                MessageBox.Show(t.Name);
    AppDomain.Unload(dynDomain);

    Does your routine die on any assembly you try to reflect types from or just SampleApplication.exe



  • Jignesh Desai

    Hi Blair,

              Iam not using any Custom Types.

                   1)  Domain1 - Loading an assembly - SampleApplication.exe
                        From next statement, the current domain starts.
                        CurrentDomain -  Using Reflection on it to get all the Types.
                          Then Iam doing some processing using Xml files. System.Xml.Xpath namespace. Used some classes in it.
                           Stored some info. in an ArrayList.
                           The above 4 lines belong to the current domain only isn't So it communication between differenct domains. I think the problem is here.
                           Unloaded the AppDomain Domain1.

                   2)   Iam using a Mono package - Mono.Cecil. to again access the same assembly - SampleApplication.exe.


                     But even if I comment out the step - 2,  Iam getting the same exception. In step - 1, as you can see Iam using only built in types.When step - 2 is written as a separate application, it is working.

                    Is it possible to have an application structure like I described here. Inorder to isolate an assembly - SampleApplication.exe Iam trying to load into two separate domains and trying to do inter domain communication.

                    What should I do


               Thank you.
                  

  • MichaelM

    ahh. . . so let me restate this so I understand.

    you have built an assembly (asm) that references a mono assembly that contains a type (sometype)

    in your main application (app) you load asm into an appdomain.

    app reflects into asm to get sometype that is unknown at compile time. you reflect on sometype to invoke methods. Processing in app modifies source for asm.sometype. You need to unload and rebuild Am I correct (sounds neat!)

    I am wondering if the problem is in the mono assembly.

    Try dynamically loading just the mono assembly. Reflecting one of the mono types that you want to use in the the dynamic assembly you are building and invoking a method on that. Do you get an error on unloading the mono assembly

    Just hashing out what I would try to solve this problem. I have no solid answer.

    But when I googled "SerializationException +CreateDomain" there is a hit for a mono patch. I wonder if thats the problem, i.e. the mono assembly was built pre-patch

    again, just guessing.



  • Ronan Jordan

    ok . . . I want to make sure we are on the same page. . .

    download this solution

    it contains two projects WindowsApplication1 and AppDomains.

    Build the solution.

    There is a Post-Build event that moves WindowsApplication.exe to Appdomains bin\debug folder with a dependency in the solution specifying that WindowsApplication depends on AppDomains to be built first.

    run AppDomains out of the debugger. clcik the button (conains the for loop I used a couple of posts ago)

    1. Does that work

    if it does, change the code in my for loop to load an exe you are having a problem with.

    2. Does that work

    if answer to #1 above is 'no', the framework is buggered.

    if answer to #2 above is 'no', there is something wrong in your exe (it is a .net exe, yes )

    if answer to #1 and #2 is yes, whats the difference between my approach and yours

    We'll get to the bottom of this!



  • Robert Djabarov

    or attaching an event to a method on the object

  • Suhayb

    Hi Blair,

              That is a nice observation. When I take that part of the code outside and put it in a separate file to check it, Iam getting the same exception on the line

     A
    ssembly myAssembly =  newDomain.Load(AssemblyName.GetAssemblyName(filename1));


    It is giving exception for any file(P.E file) except itself i.e. if I give the same application .exe file as input, it is giving correct output but If I give some other file then it is giving the same exception on the above line.


              What does this mean


  • snowbound

    Type[] types = myAssembly.GetTypes();
    foreach(Type t in types)
    {
    // Query XML file for Type t and get the path
    XPathDocument modelDoc = new XPathDocument(filename2);
    XPathDocument patternDoc = new XPathDocument(filename3);
    XPathNavigator modelNav = modelDoc.CreateNavigator();
    XPathNavigator patternNav = patternDoc.CreateNavigator();
    string cname = t.Name;

    ..................
    ..................
    }

    AppDomain.Unload(newDomain); // <<< And it dies right here (Blair)

    If so. . . does it die on any value for filename1



  • Newmer60


    Hi,

    No, Iam not building with mono. Iam just using its .dll file. I referenced its .dll file and used the types in that assembly. Iam compiling and running in VS.NET only.

  • mrenf

    are you attaching to any events on the object that you returned from the assembly

  • yi peng

    Hi,

    This is part of the code. Take a look.

    AppDomain newDomain = AppDomain.CreateDomain("NewDoamin");
    Assembly myAssembly = newDomain.Load(AssemblyName.GetAssemblyName(filename1));

    Type[] types = myAssembly.GetTypes();
    foreach(Type t in types)
    {
    // Query XML file for Type t and get the path
    XPathDocument modelDoc = new XPathDocument(filename2);
    XPathDocument patternDoc = new XPathDocument(filename3);
    XPathNavigator modelNav = modelDoc.CreateNavigator();
    XPathNavigator patternNav = patternDoc.CreateNavigator();
    string cname = t.Name;

    ..................
    ..................
    }

    AppDomain.Unload(newDomain);
    // Mono.Cecil starts here.

    AssemblyDefinition sourceAssembly = AssemblyFactory.GetAssembly
    ("MyAttributes.dll");
    AssemblyDefinition targetAssembly = AssemblyFactory.GetAssembly
    (filename1);


    Thank you.

  • Giri Nair

    so you are building with mono what happens if you build with csc and unload it

  • Noam02

    no. . . I just tried that both ways.

    you can load the assembly. . . create an instance of an object out of it. . . use it normally. . . and it blows up on the domain unload



  • Unloading an Assembly