Я работаю над вопросом, касающимся скорости нашего веб-приложения для интрасети и функции, которая получает потомков всех элементов в нашей базе данных.
У меня нет доступа к коду дома, ноЯ могу описать проблему и процесс:
У нас есть таблица базы данных, в которой хранятся элементы, которые могут быть связаны с родительским элементом в той же таблице.У нас есть логика, которая предотвращает циклические ссылки, поэтому теоретически ссылка-потомок никогда не должна возвращаться назад (пока ничего такого не произошло).
Когда пользователь заходит на страницу в веб-приложении, в настоящее время у меня есть функции, которыеполучить список потомков этого элемента и поместить его в объект.Первоначально это делалось в обычном цикле 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 секунду с возвратом всех данных со случайными ошибками.Представленное выше, похоже, работает с полным возвратом данных, но выдает случайные ошибки в случайных точках.Любые советы?