我正在開發一個項目,我必須在運行時加載程序集(讓它們調用它們的任務),運行任務,然後能夠關閉整個程序集,可以在不中斷主應用程序的情況下更換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) –