Thanks Simon, that does the trick. I was surprised - I didn't =
implemented a Dispose method on the object as it doesn't use any =
unmanaged resources. It must be the base class (ServicedComponent) that =
requires to be Disposed before it can be released. I guess it must =
create an external reference to itself in COM+ that prevents it from =
being garbage collected. Some clear documentation from Microsoft about =
this would be welcome.
Paul
[quoted text, click to view] "Simon Hart" <srhartone@yahoo.com> wrote in message =
news:ew3glZxkGHA.4596@TK2MSFTNGP02.phx.gbl...
You need to dispose the server object, setting it to null will not =
release it.
Regards
Simon.
[quoted text, click to view] "Paul Taylor" <paul.2.taylor@atosorigin.com> wrote in message =
news:OlVQW8ujGHA.3588@TK2MSFTNGP02.phx.gbl...
Below is code to demonstrate the problem.=20
Create a VS solution with three projects:
a.. a Class Library called NeverDies to contain Immortal.vb,=20
b.. a Console app called Client to contain Module1.vb=20
c.. a setup program to deploy the app to a Windows 2003 server.
Note that the Finalize method in the Immortal class contains code to =
show whether the object gets garbage collected (it doesn't).
a.. Deploy the application to a W2K3 server=20
b.. Open the Component Services snap-in=20
c.. Open a trace viewer application (download a freeware version =
of DebugView if required from
http://www.sysinternals.com/)=20
d.. run Client.exe (this may cause an error on the first run)=20
e.. refresh the COM+ Applications node and open the properties =
dialog for the NeverDies application=20
f.. if you got an error when running client.exe, set the =
application's Identity to the LocalService account,=20
g.. on the Advanced tab, select "Leave running when idle"=20
h.. OK the changes, select the components node underneath the =
NeverDies application and switch the snap-in to Status view=20
i.. if you got an error first time round, run client.exe again=20
j.. observe that the Immortal object has not been destroyed=20
k.. observe that the Finalize method produced no output in the =
Trace Viewer, demonstrating that the object was not garbage collected
*********************
Immortal.vb
*********************
Imports System.Threading
Imports System.EnterpriseServices
<EventTrackingEnabled()> _
Public Class Immortal
Inherits ServicedComponent
Private _start As DateTime
Public Sub New()
_start =3D Now
End Sub
Public Function Live() As Long
Dim rnd As New Random
Thread.CurrentThread.Sleep(rnd.Next(1, 3000))
Return Now.Subtract(_start).TotalMilliseconds
End Function
Protected Overrides Sub Finalize()
Trace.WriteLine("Finalized")
MyBase.Finalize()
End Sub
End Class
*********************
Add the following attributes to AssemblyInfo.vb in NeverDies project
*********************
<Assembly: ApplicationName("NeverDies")>=20
<Assembly: ApplicationID("{49CC81DB-C910-40ec-B5DA-DADF6DFDE917}")>=20
<Assembly: ApplicationActivation(ActivationOption.Server)>=20
<Assembly: ApplicationAccessControl(False)>=20
*********************
Module1.vb
*********************
Imports NeverDies
Imports System.EnterpriseServices
Module Module1
Sub Main()
Dim imm As New NeverDies.Immortal
Dim iLifeSpan As Integer =3D imm.Live()
imm =3D Nothing
'Force garbage collection
System.GC.Collect()
Console.WriteLine(String.Format("The object lived for {0} =
milliseconds", iLifeSpan))
Console.WriteLine("Press a key to continue...")
Console.Read()
End Sub