For several reasons I need to create a COM+ component in .Net Framework 4. The intent is to host the component in its own process (dllhost.exe), hence the usage of ActivationOption.Server.
My component code needs to persist data between object activations, which is maintained by a worker thread. This worker thread and its data are held in static (shared) members of my base class. The shared data is independent of the caller, its security context, transactions, etc. Also, the worker thread performs background processing on the data.
I need to clean up the data and orderly terminate the worker thread when the dllhost process is disposed. Since there are no static (shared) destructors, I don't know how to do it. Is there anything I could implement while inheriting ServicedComponent? Any other ideas? Thank you.
Here's some code to start:
Imports System.EnterpriseServices
<Assembly: ApplicationName("MySender")>
<Assembly: ApplicationActivation(ActivationOption.Server)>
<ClassInterface(ClassInterfaceType.None), ProgId("MySender.Sender")> _
<Transaction(EnterpriseServices.TransactionOption.NotSupported)> _
Public Class Sender
Inherits ServicedComponent
Implements SomeLib.IMsgSender
Shared worker As myWorker
Shared sync As New Object
Public Sub MyInstanceMethod(msg as string) Implements SomeLib.IMsgSender.SendMessage
SyncLock sync
If worker Is Nothing Then
worker = New myWorker
worker.StartThread()
End If
End SyncLock
worker.Process(msg)
End Sub
'Something like this does not exist!'
Shared Sub Dispose()
SyncLock sync
If worker IsNot Nothing Then
worker.StopThread()
End If
End SyncLock
End Sub
End Class
The AppDomain.ProcessExit event will fire before unloading the domain. If the code to run doesn't take too long, it could be used like this:
Imports System.EnterpriseServices
<Assembly: ApplicationName("MySender")>
<Assembly: ApplicationActivation(ActivationOption.Server)>
<ClassInterface(ClassInterfaceType.None), ProgId("MySender.Sender")> _
<Transaction(EnterpriseServices.TransactionOption.NotSupported)> _
Public Class Sender
Shared Sub New
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf MyDisposalCode
End Sub
'....
Shared Sub MyDisposalCode(sender as Object, e as EventArgs)
'My disposal code
End Sub
End Class
It's important to notice that .Net will enforce a 2 second timeout on this code.