c # ASP MVC Parallel For цикл, получение потомков, случайные ошибки - PullRequest
0 голосов
/ 15 мая 2018

Я работаю над вопросом, касающимся скорости нашего веб-приложения для интрасети и функции, которая получает потомков всех элементов в нашей базе данных.

У меня нет доступа к коду дома, ноЯ могу описать проблему и процесс:

У нас есть таблица базы данных, в которой хранятся элементы, которые могут быть связаны с родительским элементом в той же таблице.У нас есть логика, которая предотвращает циклические ссылки, поэтому теоретически ссылка-потомок никогда не должна возвращаться назад (пока ничего такого не произошло).

Когда пользователь заходит на страницу в веб-приложении, в настоящее время у меня есть функции, которыеполучить список потомков этого элемента и поместить его в объект.Первоначально это делалось в обычном цикле FOR, но время, необходимое для анализа 881 сущности, заняло бы 12+ секунд, которые необходимо изменить.Я изучил многопоточность и реализовал цикл Parallel FOR, и это заняло время от 12+ секунд до 1-2 секунд, за исключением того, что я случайно получал ошибки на странице.

Некоторые ошибки включают раскрывающийся списокне заполняется, состояние соединения не открыто и недоступно, а соединение закрыто и недоступно.

Исходный код выглядит примерно так:

var DS = _uow.locations.AllEager().FirstOrDefault( l => l.Zone == "DS");
var hwddl = new List<HWTXSelectItem>();
var HWinDS = _uow.hw.AllEager().Where(h => h.Locations_ID == DSS.Locations_ID).OrderBy(h => h.ID).ToArray();

var dataSet =_uow.hw.AllEager().Where(h => h.IsActive && h.Parent_ID != null).Select(h => new HierarchyObject() {id=h.HW_ID, parentId = Parent_ID}).ToList();
var assets = _uow.hw.AllEager();
var arrayCount = HWinDS.Length;
for(int i = 0; i < arrayCount; i++){
    var hw in HWinDS[i];
    var HWDescendants = Helpers.FindAllChildren(dataSet, new HierarchyObject() {id=hw.HWID, parendId=null}).ToList();
    var descendends = new List<int>();
descendends.AddRange(HWDescendants.Select(m => m.id);

    var allChildren = assets.Where(h => descendends.Contains(h.HW_ID) && IsActive).ToList();

    var direct = allChildren.Where(h => h.ParentID == hw.HW_ID).Select(h => new{hwid = h.HWID, id=h.HW_ID}).OrderBy(h => h.hwid).ToList();
    var sub = allChildren.Where(h => h.Parent_ID != hw.HW_ID).Select(h => new{hwid = h.HWID, id=h.HW_ID}).OrderBy(h => h.hwid).ToList();

    hwtxddl.Add(new HWTXSelectItem
    {
    ...
    ... <obj properties>
    ...
    });
}

HWFromDS = hwddl;

Распараллелено это что-то вроде:

var DS = _uow.locations.AllEager().FirstOrDefault( l => l.Zone == "DS");
var hwddl = new List<HWSelectItem>();
var HWinDS = _uow.hw.AllEager().Where(h => h.Locations_ID == DS.Locations_ID).OrderBy(h => h.ID).ToArray();

var dataSet =_uow.hw.AllEager().Where(h => h.IsActive && h.Parent_ID != null).Select(h => new HierarchyObject() {id=h.HW_ID, parentId = Parent_ID}).ToList();
var items = _uow.hw.AllEager();
var arrayCount = HWinDS.Length;
Parallel.For(0, arrayCount,i =>
{
    var hw in HWinDS[i];
    var HWDescendants = Helpers.FindAllChildren(dataSet, new HierarchyObject() {id=hw.HW_ID, parendId=null}).ToList();
    var descendends = new List<int>();
descendends.AddRange(HWDescendants.Select(m => m.id);

    var allChildren = assets.Where(h => descendends.Contains(h.HWAssets_ID) && IsActive).ToList();

    var direct = allChildren.Where(h => h.Parent_ID == hw.HW_ID).Select(h => new{hwid = h.HWID, id=h.HW_ID}).OrderBy(h => h.hwid).ToList();
    var sub = allChildren.Where(h => h.Parent_ID != hw.HW_ID).Select(h => new{hwid = h.HWID, id=h.HW_ID}).OrderBy(h => h.hwid).ToList();

    hwddl.Add(new HWSelectItem
    {
    ...
    ... <obj properties>
    ...
    });
}

HWFromDS = hwddl;

У меня есть несколько вариантов параллельных циклов for, которые работают и ускоряют процесс, получая общее время 6 секунд с частичным возвратом данных без ошибок и 1 секунду с возвратом всех данных со случайными ошибками.Представленное выше, похоже, работает с полным возвратом данных, но выдает случайные ошибки в случайных точках.Любые советы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...