gpt4 book ai didi

c# - 从 TypeBuilder.CreateType 返回的类型的 Activator.CreateInstance 抛出 ArgumentException

转载 作者:太空狗 更新时间:2023-10-30 01:34:34 26 4
gpt4 key购买 nike

我想在运行时创建类型并通过 Activator.CreateInstance 实例化它。我正在使用 Refletion.Emit 来执行此操作,当创建和实例化类型的方法在单个线程中运行时,一切正常。然而,当我尝试在多个线程中运行相同的方法时,会抛出一个 ArgumentException。

代码类似于:

class TypeBuilder
public IMyType Build() {
Type type = GetDynamicType("MyDynamicType");
IMyType myType = (IMyType) Activator.CreateInstance(type);
return myType;
}

Type GetDynamicType(string typeName) {
// define the module builder...
ModuleBuilder module = ...
Type type = module.GetType(typeName);
if (type == null) {
type = MakeDynamicType(typeName);
}
retyrn type;
}

Type MakeDynamicType(string typeName) {
lock(lock_) { // lock_ is a static variable
// ensure that the type was not already created by another thread.
Type type =
module
.GetType(typeName);
if (type != null) {
return type;
}
// define the type builder...
TypeBuilder builder = ...

// define the type body...

return type.CreateType();
}
}
}

一些观察:

  • 仅当多个线程尝试创建该类型时才会抛出异常。
  • 第一次调用该方法并抛出异常时,返回的类型派生自 TypeBuilder 而不是 RunTimeType,但第二次调用该方法时,该类型派生自 RunTimeType。

更新 1:

异常消息是:“类型必须是运行时提供的类型。”

更新 2:

完整的源代码托管在 GitHub

最佳答案

也许是一个迟到的答案,但无论如何。

在您的代码中,GetDynamicType不是线程安全的,有两个未处理的竞争条件。其中比较有趣的是:

一个线程用ModuleBuilder.DefineType(...)定义了一个新类型.它得到 TypeBuilder然后使用它来构建类型的对象。

同时,另一个线程调用ModuleBuilder.GetType(...)并获得 Type它寻找的对象……至少它是这么认为的。它假设它得到了 RuntimeType ,但实际上,它得到了 TypeBuilder由第一个线程构建。

仅当第一个线程调用TypeBuilder.CreateType()时, TypeBuilder替换为相应的 RuntimeTypeModuleBuilder .

所以你最终会尝试 Activator.CreateInstanceTypeBuilder ,它会抛出“类型必须是运行时提供的类型”异常。

我建议重写 GetDynamicType函数并使用 ConcurrentDictionary<string, Type>MakeDynamicType作为值(value)工厂:

  private readonly ConcurrentDictionary<string, Type> _dynamicTypesByName = 
new ConcurrentDictionary<string, Type>();

Type GetDynamicType(string typeName) {
// define the module builder...
ModuleBuilder module = ...
return _dynamicTypesByName.GetOrAdd(typeName, MakeDynamicType);
}

关于c# - 从 TypeBuilder.CreateType 返回的类型的 Activator.CreateInstance 抛出 ArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30201509/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com