Note that there are some explanatory texts on larger screens.

plurals
  1. POLoad, Use and the Unload an Assembly at runtime
    text
    copied!<p>I am working on a project where I have to load assemblies (lets call them tasks) at runtime, run the task and then be able to kill off the whole assembly so that the dll can be replaced without interrupting the main application.</p> <p>There are many of these tasks running within the main application, some run sequentially and some run in parallel. Occasionally one or to of these tasks need to be updated and then re-added to the queue. Currently we are stopping the entire application and interrupting the other tasks at whatever stage they are at, which is not ideal.</p> <p>I have figured out that I will have to load each assembly into a separate AppDomain, but loading the assemblies in those domains is proving difficult, especially when I need to actually run the tasks and receive events from them. I have been looking into this problem for a couple of days and have still not managed to get a working proof-of-concept.</p> <p>I have an Interface for the tasks which includes a 'run' and 'kill' method (subs) and a 'taskstep', 'complete' and 'killed' event. 'taskstep' returns an object to be cached later, 'complete' fires when the whole task is done and 'killed' fires when it is ready to be unloaded. There should also be a timeout on the whole process of two hours and a timeout of 2 minutes on the killed event in case it gets stuck, at which point I would like to be able to unload it, forcing any threads to terminate (which is what 'kill' should do anyway). Each assembly may contain several tasks, all of which should loadable be unloadable.</p> <p>I have no problems loading these tasks as 'plugins' but am lost when trying to both use them and unload them. If I have to create some elaborate wrapper then so be it but is what I need even possible?</p> <p>I have tried inheriting from MarshalByRefObject but I do not even know the assembly fullname unless I load it first, which then locks the file. I have tried loading from a byte array of the assembly. This means that the file is not locked but a copy of it remains in the current appdomain. This will become problematic over the following months / years!</p> <pre><code>For Each key As String In assemblies.Keys Dim ad As AppDomain = AppDomainHelper.BuildChildAppDomain(AppDomain.CurrentDomain, key) AddHandler ad.AssemblyResolve, AddressOf AssemblyResolve _l.Add(ad) For Each value As String In assemblies(key) Dim item As IScanner = CType(ad.CreateInstanceAndUnwrap(key, value), IScanner) ListBox1.Items.Add(item) Next Next Private Function AssemblyResolve(sender As Object, args As ResolveEventArgs) As Assembly Return GetType(IScanner).Assembly End Function </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload