[英]Marshalling Assembly from another AppDomain
是否可以從另一個應用程序域保存對程序集的引用,而無需將該程序集加載到當前的應用程序域中?
我正在修復Windows服務中的內存泄漏,該服務動態生成程序集並運行動態生成的代碼。 問題是生成的程序集被加載到當前應用程序域中,永遠不能卸載。
其中一個Windows服務庫中有一個方法具有以下簽名:
public Assembly CreateMethod(ObservableCollection<Field> sourceFields, Field destinationField)
此方法為程序集創建代碼並使用CSScript庫LoadMethod函數加載它:
result = CSScript.LoadMethod(scriptFunction.ToString());
稍后,來自CreateMethod的此程序集引用用於在生成的程序集內運行函數。
public object Run(Field destinationField, ObservableCollection<LinkField> sourceLinkFields, DataRow mainRow, Assembly script) {
...
var method = script.GetStaticMethodWithArgs("*.a" + Id.ToString().Replace("-", String.Empty), argumentTypes.ToArray());
return method(arguments.ToArray());
}
我想知道是否可以將動態生成的程序集加載到另一個應用程序域中,並通過某種類型的代理運行它們,而無需將其加載到當前的應用程序域中。
編輯:
我想知道當程序集加載到另一個AppDomain中時是否可以在一個AppDomain中使用Assembly
類引用。 查看MSDN文檔,它們展示了如何使用MarshalByRefObject。 基本上我試圖避免將簽名更改為我的CreateMethod函數,但是如果不可能的話,我可能需要將其更改為返回MarshalByRefObject。
更新:
我最后在另一個應用程序域中調用了CSScript.LoadMethod,我保留了一個詞典,然后讓CreateMethod返回一個Guid而不是一個Assembly,然后我傳遞這個Guid直到Run調用。 Run調用現在將Guid作為參數而不是Assembly。 在Run調用中,我將Guid傳遞給另一個app域,運行該方法,並通過繼承MarshalByRefObject的類返回結果對象。
這是AppDomain的主要功能之一! 只需看看文檔
如果您不想在主AppDomain中使用動態程序集,則必須將CreateMethod
移動到另一個AppDomain,因為只要有一個Assembly
實例,它就會被加載。 換句話說,不能在另一個應用程序域中保存對程序集的引用,只能跨應用程序域調用該程序集。
在不更改簽名和一堆代碼的情況下,您似乎需要移動最小量:1)程序集創建和2) Run
。 然后執行Run
marshall的結果。
就CreateMethod
我認為您希望其他程序集中的方法“包裝” CreateMethod
並返回可以傳遞給Run
某種令牌。 這幾乎就像改變簽名一樣......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.