Ich habe eine Wrapper-Klasse, die in einer MVC-Anwendung verwendet wird, die die Elemente in einer Auflistung durchläuft und überprüft, ob der aktuelle Benutzer die Berechtigung zum Zugriff auf dieses Element hat es für die Anzeige. Zum größten Teil funktioniert es wie ein Zauber. Für einen bestimmten Objekttyp läuft es jedoch wie ein absoluter Hund und ich kann nicht herausfinden warum.Schreckliche Leistung von MoveNext innerhalb der Klasse, die IEnumerable implementiert <T>
Klassen Die Schnittstelle werden wie folgt geschrieben:
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();
}
Nun meine erste Frage ist mein Verständnis überprüfen, was hier vor sich geht. Ich bin wahrscheinlich falsch, aber mein Verständnis ist, dass, wenn ich versuche, eine foreach-Schleife gegen eine Sammlung von Typ-Objekten zu verwenden nie System.Collections.IEnumerable.GetEnumerator() - sicherlich, dass Code nie getroffen wird?
Das Problem liegt, wenn ich diesen Wrapper für Protokolldateieinträge verwenden, die über Entitätsframework in einer LogEntryViewDaya-Klasse bereitgestellt werden. Wenn der Code innerhalb von GetEnumerator auf die foreach-Schleife trifft, hält er für volle 6-8 Sekunden an, obwohl nur 20 Elemente in der Enumeration vorhanden sind!
Hier ist der Code für 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; } }
}
Soweit ich sagen kann, es in Instanziieren diese Klassen keine nennenswerte Leistung ist - setzen Sie einen Haltepunkt im Konstruktor und F5ing durch scheint glatt wie nichts.
Warum also ist eine Sammlung dieser bestimmten Objekte so langsam zu durchlaufen? Ich habe keine Ahnung: Vorschläge dankbar geschätzt.
Okay, werde hier meine Unwissenheit zeigen, aber ich hatte angenommen, dass die Klasse bevölkert war, als ihr Konstruktor aufgerufen wurde? Das passiert, bevor es jemals in die foreach Schleife kommt und scheint mit einer befriedigenden Geschwindigkeit aufzutreten. –
@Matt: Nun, Sie haben in einem IEnumerable übergeben, aber das könnte faul ausgewertet werden. Insbesondere, wenn Sie ein IQueryable übergeben, übergeben Sie die * Abfrage * und nicht die Ergebnisse der Auswertung dieser Abfrage.Abgesehen von allem anderen könnten Sie Ihren Konstruktor so ändern, dass er 'ToList()' aufruft und diese Liste speichert, was die Ausführung der Abfrage erzwingt. Grundsätzlich können wir hier nicht genug Code sehen, um zu wissen, was vor sich geht. –
Was brauchen Sie mehr? –