У меня есть класс-оболочка, который используется в приложении MVC, который предназначен для циклического перемещения элементов в коллекции и проверки того, что у текущего пользователя есть авторизация для доступа к этому элементу перед возвратом это для отображения. По большей части это работает как шарм. Однако для одного конкретного типа объекта он работает как абсолютная собака, и я не могу понять, почему.Ужасная производительность MoveNext внутри класса, реализующего IEnumerable <T>
классыИнтерфейс записываются так:
private readonly IEnumerable<T> _ViewData;
public IEnumerator<T> GetEnumerator()
{
foreach (T item in _viewData)
{
if (item.UserCanEdit || item.UserCanView)
yield return item;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
Теперь мой первый вопрос, это проверить мое понимание того, что здесь происходит. Я, вероятно, ошибаюсь, но я понимаю, что когда я пытаюсь запустить цикл foreach против коллекции объектов типа, ему никогда не нужно использовать System.Collections.IEnumerable.GetEnumerator() - неужели этот код никогда не попадает?
Проблема заключается в том, что я пытаюсь использовать эту оболочку для записей в файле журнала, которые доставляются через сущность framework в классе LogEntryViewDaya. Когда код попадает в цикл foreach внутри GetEnumerator, он останавливается на полные 6-8 секунд, хотя в перечислении всего 20 элементов!
Вот код для LogEntryView
public class LogEntryViewData:BaseViewData
{
private LogEntry _entry;
public LogEntryViewData(LogEntry entry, ICustomerSecurityContext securityContext) : base(securityContext)
{
_entry = entry;
}
public string Application { get { return _entry.Application; } }
public string CurrentUser { get { return _entry.CurrentUser; } }
public string CustomerName { get { return _entry.CustomerName; } }
public DateTime Date { get { return _entry.Date; } }
public string Exception { get { return _entry.Exception; } }
public string HostName { get { return _entry.HostName; } }
public long Id { get { return _entry.Id; } }
public string Level { get { return _entry.Level; } }
public string Message { get { return _entry.Message; } }
public int? ProcessId { get { return _entry.ProcessId; } }
public int? ServiceId { get { return _entry.ServiceId; } }
public string ServiceName { get { return _entry.ServiceName; } }
public int? TaskId { get { return _entry.TaskId; } }
public int? TaskName { get { return _entry.TaskName; } }
public string Thread { get { return _entry.Thread; } }
}
Насколько я могу сказать, что нет никакой заметной производительности в инстанцировании этих классов - положить точку останова в конструкторе и F5ing через кажется гладкая, как и все.
Итак, почему коллекция этих конкретных объектов настолько медленна, чтобы проходить через итерацию? Я понятия не имею: предложения с благодарностью оценили.
Хорошо, я покажу свое невежество, но я предположил, что класс был заселен, когда его конструктор был вызван? Это происходит до того, как он когда-либо попадает в петлю foreach и, кажется, происходит с удовлетворительной скоростью. – 2010-12-09 14:11:55