Запуск PLINQ на унаследованных объектах создает исключение AccessViolationException - PullRequest
0 голосов
/ 11 февраля 2012

Я столкнулся с узким местом при тестировании приложения, которое взаимодействует с базой данных SQL-Compact 3.5 с EF.

Обычно, когда я сталкиваюсь с таким узким местом, я переделываю запрос linq, чтобы уменьшить количество выполненных запросов linq, потому что повторный запуск одного и того же запроса linq в дюжину раз для базы данных, заполненной тысячами записей, создает немного накладные расходы. Затем я использую plinq для ускорения времени создания.

Это работало довольно хорошо, пока я не попытался сделать это с таблицей ShapeEntities.

ShapeEntity - это абстрактный объект, который работает в качестве базового класса для других объектов, которые практически идентичны друг другу. Я не могу запустить это с помощью метода AsParallel ().

HashSet<Guid> keys ...

var x = 
    from shape in model.ShapeEntities.AsParallel()
    where keys.Contains(shape.ImageKey)
    select shape;

List<ShapeEntity> shapes = new List<ShapeEntity>(x);

Если бы я удалил AsParallel () из приведенного выше кода, выполнение запроса занимает около 1,4 секунды, когда мы помещаем его в список. С помощью метода AsParallel () я получаю AccessViolationException примерно через 40 секунд. Это никогда не проходит мимо создания.

У кого-нибудь есть идеи, как это ускорить? Я не могу сделать ImageEntity.ShapeEntities, потому что тогда он превращается в 1,2 секунды на ImageEntity.

1 Ответ

0 голосов
/ 11 февраля 2012

Контекст структуры сущности не является потокобезопасным. Из MSDN

Класс ObjectContext не является потокобезопасным.Целостность объектов данных в ObjectContext не может быть обеспечена в многопоточных сценариях.

Если вы извлекаете эти объекты только для чтения, вы можете сэкономить несколько миллисекунд, используя NoTracking MergeOption

model.ShapeEntitie.MergeOption = MergeOption.NoTracking; 

В противном случае реализовать механизм подкачки.

...