我从这里抓住了System.
Linq.Dynamic.DynamicQueryable:
我遇到的问题是代码如下所示:
var results = dataContext.GetTable<MyClass>.Select("new (MyClassID, Name, Description)").Take(5);
看来,如果这行代码由多个线程同时执行,那么Microsoft的动态Linq代码会在他们的ClassFactory.GetDynamicClass()方法中崩溃,如下所示:
public Type GetDynamicClass(IEnumerable<DynamicProperty> properties)
{
rwLock.AcquireReaderLock(Timeout.Infinite);
try
{
Signature signature = new Signature(properties);
Type type;
if (!classes.TryGetValue(signature, out type))
{
type = CreateDynamicClass(signature.properties);
classes.Add(signature, type); // <-- crashes over here!
}
return type;
}
finally
{
rwLock.ReleaseReaderLock();
}
}
崩溃是一个简单的字典错误:“已经添加了具有相同密钥的项目.”
在Ms代码中,rwLock变量是一个ReadWriterLock类,但是它不会阻止多个线程进入类内部.如果语句,则尝试GetGetValue(),显然,Add将失败.
我可以在任何创建两个或多个尝试执行Select(“new”)语句的线程的代码中轻松复制此错误.
无论如何,我想知道是否有其他人遇到过这个问题,如果有修复或解决方法,我可以实现.
谢谢.
最佳答案 我做了以下(需要.NET 4或更高版本才能使用System.Collections.Concurrent):
>将classes字段更改为ConcurrentDictionary< Signature,Type> ,
>删除了所有ReaderWriterLock rwLock字段以及引用它的所有代码,
>将GetDynamicClass更新为:
public Type GetDynamicClass(IEnumerable<DynamicProperty> properties) {
var signature = new Signature(properties);
return classes.GetOrAdd(signature, sig => CreateDynamicClass(sig.properties));
}
>删除了classCount字段并更新了CreateDynamicClass以使用classes.Count:
Type CreateDynamicClass(DynamicProperty[] properties) {
string typeName = "DynamicClass" + Guid.NewGuid().ToString("N");
...