从另一个 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 而不是程序集,然后我传递这个 Guid 直到运行称呼。 Run 调用现在采用 Guid 作为参数,而不是程序集。在 Run 调用中,我将 Guid 传递到其他应用程序域,运行该方法,并通过继承 MarshalByRefObject 的类返回结果对象。
Is it possible to hold a reference to an Assembly from another appdomain without having that assembly loaded into the current appdomain?
I'm working on fixing a memory leak in a Windows Service that dynamically generates Assemblies and runs the dynamically generated code. The problem is the generated Assemblies are loaded into the Current app domain and can never be unloaded.
There is a method in one of the Windows Service libraries that has the follow signature:
public Assembly CreateMethod(ObservableCollection<Field> sourceFields, Field destinationField)
This method creates the code for the assembly and loads it with the CSScript library LoadMethod function:
result = CSScript.LoadMethod(scriptFunction.ToString());
Later this Assembly reference from CreateMethod is used to run a function inside the generated assembly.
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());
}
I'm wondering if it is possible to load the dynamically generated assembly into another app domain and run them through some type of proxy without having it loaded into the current app domain.
Edit:
I want to know if I can use an Assembly
class reference in one AppDomain when the assembly is loaded in another AppDomain. Looking at the MSDN documentation they show how to use MarshalByRefObject. Basically I am trying to avoid changing the signature to my CreateMethod function, however I may need to change it to return MarshalByRefObject if this is not possible.
Update:
I ended up putting the call to CSScript.LoadMethod in the other app domain where I keep a Dictionary I then made CreateMethod return a Guid instead of an Assembly and then I pass this Guid around until the Run call. The Run call now takes a Guid as an argument instead of an Assembly. Inside the Run call I pass the Guid to the other app domain, run the method, and return the result object through a class that inherits MarshalByRefObject.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您不想在主 AppDomain 中使用动态程序集,则必须将
CreateMethod
移动到另一个 AppDomain,因为一旦您拥有Assembly
的实例,它就已被删除。已加载。换句话说,不可能在另一个应用程序域中保存对程序集的引用,而只能跨应用程序域调用该程序集。在不更改签名和一堆代码的情况下,您似乎需要移动最少的数量:1) 程序集创建和 2)
Run
。然后执行Run
编组结果。至于
CreateMethod
,我认为您希望另一个程序集中的方法“包装”CreateMethod
并返回某种可以传递给Run
的令牌代码>.这几乎就像在某种程度上改变签名一样......If you don't want the dynamic assembly in your main AppDomain, you have to move
CreateMethod
to another AppDomain, because as soon as you have an instance ofAssembly
, it's been loaded. In other words, no it is not possible to hold a reference to an assembly in another application domain, only to call into that assembly across application domains.Without changing the signature and a bunch of your code, it seems like you need to move the minimum amount: 1) assembly creation and 2)
Run
. Then have the implementation ofRun
marshall the results.As far as
CreateMethod
I think you want a method in the other assembly to "wrap"CreateMethod
and return some sort of token that can be passed toRun
. It's almost like changing the signature in a way...这是 AppDomain 的主要功能之一!直接去看文档就可以了
This is one of the major features of an AppDomain! Just go look at the documentation