.net object dispose


L

laputa

Dear all :

I create a simple code (window application) like following
Private Sub Button1_Click()
Dim Obj As Object
Dim asm As Assembly = Assembly.LoadFrom("TestApp.dll")
Dim ty As Type = asm.GetType("TestApp.appServ")
Obj = Activator.CreateInstance(ty)
Dim Istring As String = Obj.funct()
MessageBox.Show(Istring)
Obj.Dispose()
GC.SuppressFinalize(Obj)

Obj = Nothing
end sub

while TestApp.dll code follow that
using System;
using System.Collections.Generic;
using System.Text;

namespace TestApp
{
public class appServ : IDisposable
{
private bool disposed = false;
public string funct()
{
return "aad";
}
~appServ()
{

// call Dispose with false. Since we're in the
// destructor call, the managed resources will be
// disposed of anyways.
Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// dispose-only, i.e. non-finalizable logic
}

// shared cleanup logic
disposed = true;
}
}



public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
GC.Collect();
}

}
}



Before the button click the "TestApp.dll" allow be overwrite
but after button click , the file is locked until the main program exit.
Can anyone tell me how to solve it ?

Thanks

Michael
 
Ad

Advertisements

T

TDC

Dispose has nothing to do with the dll being locked. That's just they
way dlls are treated when loaded by a process wthin Windows.
 
M

Michel Posseth [MCP]

AFAIK


dll`s are locked as long as the app domain is loaded , so create seperate
app domains if you want the dll to be freed
hth

michel
 
C

Cor Ligthert[MVP]

There is no net object dispose in the context of your subject.

Every object inherited from components has a method to release unmanaged
resources.

The name of the method (shortcut) to invoke do this is dispose (unmanaged
resources).

However it has in fact (as long as this is not overridden to do other
things) only slightly to do with the dispose of an object itself.

It is strongly advised to do in Net nothing about destruction of objects
yourself as this is done by managed code.

Doing the destruction yourselfs can lead to unpredictable results.

Cor
 
Ad

Advertisements

M

Michel Posseth [MCP]

Hello Michael



' Assembly you want to load
Dim assemblyFileName As String = "D:\Test\TestApp.dll"
Dim assemblyName As String = "Test"

' Setup the evidence
Dim evidence As New Evidence(AppDomain.CurrentDomain.Evidence)
Dim TestDomain As AppDomain = AppDomain.CreateDomain(
"TestDomain", ' The friendly name of the domain.
evidence, ' Evidence mapped through the security policy to establish a
top-of-stack permission set.
AppDomain.CurrentDomain.BaseDirectory, ' The base directory that the
assembly resolver uses to probe for assemblies.
System.IO.Path.GetFullPath(assemblyFileName), ' The path relative to
the base directory where the assembly resolver should probe for private
assemblies.
True) ' If true, a shadow copy of an assembly is loaded into this
application domain.

Console.WriteLine(TestDomain.Load(assemblyName).FullName)

' You use the assembly

AppDomain.Unload(TestDomain) ' Unload the AppDomain

AppDomain.Unload should unlock the assembly loaded into that appDomain. ,
you load the assembly into your main appDomain. In which case, you will
lock it until you shutdown your application and thus that appDomain is
unloaded .


Lifeng Lu MSFT for VB once showed this verry nice example

<<<<

I think I will do is not to call AppDomain.Load function, but you create an
agent class, which must be a MarshalByRefObject class in your application.
After you create the appDomain, you create an instance of that Agent class
in the appDomain, and in your main appDomain, you can get a marshalled
handler of this agent, and then, you call its function. Only in that
function, which will run inside the sub appDomain will load that seperated
assembly, and uses its functions.



Your code would look like:

Class AgentInAppDomain

Inherits MarshalByRefObject

Sub RunFunctionInAppDomain(...)

Try

dim yourAssembly As Assembly = Assembly.LoadFrom(...)

' do what you need do here...

Catch ex As Exception

Throw new InvalidOperationException(ex.Message)

End Try

End Sub

End Class



In your main function

Dim subDomain As AppDomain = AppDomain.CreateDomain(...)

dim agent as AgentInAppDomain =
subDomain.CreateInstanceAndUnwrap(GetType(AgentInAppDomain).Assembly.GetName().FullName,
GetType(AgentInAppDomain).FullName)

agent.RunFunctionInAppDomain()

....

subDomain.Unload()



You can fill in the details. Remember you should not pass any type defined
in that assembly into your main appDomain, including exceptions, otherwise,
you would load that assembly into your main appDomain.



Lifeng Lu

MS VB



I hope that above examples give you an idea how you can solve your problem ,
the Locking is not because of the Dispose but because of the appDomain
still beeing loaded wich in its turn locks the Dll



HTH



Michel Posseth [MCP]

http://www.vbdotnetcoder.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top