使用AssemblyBuilder构建动态程序集时,可以创建类型并立即开始使用它。如果以后需要向程序集添加另一种类型,也可以这样做,而且似乎一切正常(就我所知)。
但是,如果有两个线程正在尝试为该程序集构建类型呢?或者如果一个准备好的类型已经在使用中,而另一个正在制作中呢?是否会出现任何冲突或竞争条件?
添加:好吧,我认为需要更多信息。
我使用Reflection.Emit在运行时动态实现接口。基本上我有这样的东西:
class MagicClass
{
public static T GetImplementation<T>();
}
需要注意的是,T
必须是一个接口,并且还有一些其他无关的要求。
每个接口都将有唯一的实现,而该实现将恰好有一个实例。它们都是线程安全的单例。
因此,当请求新的、以前未见过的接口时,我会实现它,创建一个实例,然后将其缓存到永久存储器中(这里定义为“直到我的程序停止”)。
但是,这将在 ASP.NET Web 应用程序中完成,因此我们有许多线程一直在请求接口。性能很重要,我正在尝试确定我可以承受多少多线程。
很明显,一个接口只会被一个线程实现。但是我能否同时在两个不同的线程中实现两个不同的接口呢?我想答案是“最好不要”。
好吧,我可以添加一个锁,只有一个线程同时执行实现。这将解决构建器相互干扰的问题。但是那些先前实现的接口呢?在制作新接口的同时,其他线程正在同时使用它们。我想它们没问题,除非它们试图在自己的程序集上使用某种反射?
当然,我可以制定每个接口实现一个程序集的策略,但这将大量占用“已加载模块”调试器窗口的空间。此外,我不知道拥有 100 个已加载程序集会产生什么性能影响(但我怀疑它们不会很好)。
第二次添加:好吧,我的语言肯定有问题,因为人们似乎不理解它。让我尝试举个代码例子:
var object1 = MagicClass.GetImplementation<I1>();
DoSomethingInAnotherThread(object1);
var object2 = MagicClass.GetImplementation<I2>();
< p>在DoSomethingInAnotherThread(object1)和MagicClass.GetImplementation<I2>()之间是否可能存在与线程相关的错误?
我们可以假设:
DoSomethingInAnotherThread(object1)不会调用MagicClass.GetImplementation<T>()
DoSomethingInAnotherThread(object1)不会对object1使用反射,object1本身也不会使用反射。
基本上,问题是 - 因为另一个线程正在重新组织程序集,所以对object1.SomeMethod()进行无辜的调用是否会崩溃。