Я взял System.Linq.Dynamic.DynamicQueryable отсюда:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Проблема, с которой я сталкиваюсь, заключается в коде, который выглядит следующим образом:
var results = dataContext.GetTable<MyClass>.Select("new (MyClassID, Name, Description)").Take(5);
Похоже, что если эта строка кода выполняется несколькими потоками, находящимися рядом одновременно, динамический код Linq от Microsoft падает в их методе 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, но она ничего не делает для того, чтобы блокировать попадание нескольких потоков внутрь классов. Оператор ifGetValue () if, так что ясно, Add не будет работать.
Я могу довольно легко воспроизвести эту ошибку в любом коде, который создает два или более потоков, которые пытаются выполнить оператор Select ("new").
В любом случае, мне интересно, сталкивался ли кто-нибудь еще с этой проблемой, и есть ли исправления или обходные пути, которые я мог бы внедрить.
Спасибо.