我正在开发一个项目,我必须在运行时加载程序集(让它们调用它们的任务),运行任务,然后能够关闭整个程序集,可以在不中断主应用程序的情况下更换dll。在运行时加载,使用和卸载程序集
这些任务中有许多运行在主应用程序中,有些运行顺序,有些运行并行。偶尔需要更新一个或这些任务,然后重新添加到队列中。目前,我们正在停止整个应用程序,并在任何阶段中断其他任务,这并不理想。
我已经知道,我将不得不将每个程序集加载到单独的AppDomain中,但在这些域中加载程序集证明是困难的,特别是当我需要真正运行任务并从中接收事件时。我一直在研究这个问题几天,仍然没有设法得到一个工作证明概念。
我有一个包含'run'和'kill'方法(subs)和'taskstep','complete'和'killed'事件的任务接口。 'taskstep'返回一个对象以后被缓存,'complete'在整个任务完成时触发,'已杀死'在准备好卸载时触发。在两个小时的整个过程中也应该有一个超时,如果被阻塞的事件超时了2分钟,那么我希望能够卸载它,强制任何线程终止(这是无论如何,“杀”应该做什么)。每个程序集可能包含多个任务,所有这些任务都应该是可加载的,无法加载。
我没有问题将这些任务作为“插件”加载,但在尝试使用它们并将其卸载时丢失了。如果我必须创建一些精心制作的包装,那就这样吧,但是我甚至需要甚么可能?
我试过继承自MarshalByRefObject,但我甚至不知道程序集全名,除非我先加载它,然后锁定文件。我已经尝试从程序集的字节数组中加载。这意味着该文件没有被锁定,但它的一个副本保留在当前的appdomain中。这会在接下来的几个月/几年中出现问题!
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
什么似乎是加载每个程序集在它自己的appdomain的问题?这是我过去采取的方法。 –
我不知道Assembly.fullname直到运行时没有加载它first.how我可以加载到自己的appdomain程序集当我只知道它的文件路径,谢谢你的答复。 –
System.Reflection.AssemblyName.GetAssemblyName(path) –