2017-01-23 6 views
0

zu ersetzen Ich möchte eine MVC-Anwendung erstellen, die das Sitzungsobjekt mit dem Cachemechanismus von .net Framework 4.0 ersetzt.C# MVC, das MemoryCache verwendet, um Sitzung

Die Anwendung muss einige Werte in einer Art Cache speichern, um den Datenbankverkehr und die Ladezeiten gering zu halten (z. B. Einstellungen, Dropdown-Werte usw.). Die Benutzer authentifizieren sich mit einem Benutzernamen und einem Passwort. Die Standard FormsAuthentication wird hier verwendet. Meine Idee war es, eine einzigartige MemoryCache für jeden Benutzer und eine allgemeine MemoryCache für die Anwendung zu erstellen.

Mein Getter für den Benutzer sieht MemoryCache wie dies

private MemoryCache _memCache 
{ 
    get 
    { 
     if(HttpContext.Application[User.Identity.Name] == null) 
     { 
      HttpContext.Application[User.Identity.Name] = new MemoryCache(User.Identity.Name); 
     } 

     return HttpContext.Application[User.Identity.Name] as MemoryCache; 
    } 
} 

Wenn ein Benutzer der Cache angeordnet werden abmeldet.

Dies ist die globale MemoryCache für die Anwendung

private MemoryCache _appMemCache 
{ 
    get 
    { 
     if(HttpContext.Application["ApplicationMemoryCache"] == null) 
     { 
      HttpContext.Application["ApplicationMemoryCache"] = new MemoryCache("ApplicationMemoryCache"); 
     } 

     return HttpContext.Application["ApplicationMemoryCache"] as MemoryCache; 
    } 
} 

Die Frage ist, ob das Anwendungsobjekt verwendbar ist die MemoryCache zu speichern. Und wenn die CacheItemPolicy ohne Probleme damit arbeitet.

Der Grund für mich, die Sitzung nicht zu verwenden, ist die mögliche Zeitüberschreitung und das Blockieren der parallelen Anforderung.

+0

Siehe [Denken Sie zweimal über den Sitzungsstatus nach] (https://brockallen.com/2012/04/07/think-twice-about-using-session-state/) - es besagt ausdrücklich, dass der Sitzungsstatus nicht der ist Ort zum Speichern von Benutzerprofildaten. Aber ich stimme @ChrisPratt zu, sollten Sie versuchen, den Sitzungsstatus zu eliminieren oder zu minimieren, anstatt komplizierte Wege zu finden, diesen zu ersetzen. – NightOwl888

Antwort

1

Dies ist aus mehreren Gründen eine schlechte Idee. In erster Linie ist MemoryCache sowohl flüchtig als auch prozessgebunden. Es wird versucht, die Sitzungsdaten beizubehalten, auch wenn sie in proc gespeichert werden, der Cache jedoch als vollständig verfügbar angesehen wird. Wenn der Speicher knapp wird, wird er fast sofort verworfen. Außerdem wird dadurch jede Möglichkeit, Ihre App auf mehrere Worker (Prozesse) zu skalieren, wirkungslos aufgehoben, da jede Version über die Version des Caches verfügen würde, was bedeutet, ob die "Sitzung" des Benutzers wiederhergestellt wurde oder nicht auf welchen Prozess sie mit ihrer nächsten Anfrage hin ankamen.

Ihre Gründe, nicht nur Session zu verwenden, machen keinen Sinn. Ja, Sitzungen haben Timeouts, aber diese sind etwas behoben, vorausgesetzt, Sie verwenden nicht in proc. Auch bei in proc wird die Sitzung in einem festen Intervall ablaufen, solange so etwas wie App-Pool-Recycles oder ähnliches nicht stattfindet. Im Gegenteil, MemoryCache könnte jederzeit unter gehen. Es gibt keine Garantie dafür, wie lange die Daten bestehen bleiben oder ob sie überhaupt bestehen bleiben. Nur weil Sie es für ein Jahr festgelegt haben, heißt das nicht, dass es nicht in fünf Minuten verworfen wird, je nachdem, was sonst noch im System vor sich geht.

Soweit "blockierende parallele Anfragen" gehen, bin ich nicht sicher, worüber Sie damit sprechen. Die Sitzung ist Thread-sicher und sollte theoretisch parallele Anfragen erlauben. Bei asynchronen Prozessen wie dem Schreiben in einen Sitzungsspeicher treten immer Gleichzeitigkeitsprobleme auf, aber diese Probleme treten auch bei MemoryCache auf.

All das gesagt, die Dinge, die Sie über das Speichern sprechen, gehören sowieso nicht in eine Sitzung. Während Sie Gründe für die Verwendung von etwas wie MemoryCache sind völlig ungültig, sollten Sie tatsächlich einen Cache verwenden, um diese Art von Sachen zu speichern. Mit anderen Worten, verwenden Sie einfach den Cache und versuchen Sie nicht, die Sitzung irgendwie durch den Cache zu ersetzen.

Auch, wie ich bereits erwähnt, gibt es ernsthafte Probleme mit MemoryCache in Multiprozess-Szenarien. Wenn Sie eine App erstellen, die immer mehr als einer Handvoll Benutzer dient, sollten Sie MemoryCache vollständig vermeiden und stattdessen etwas wie Redis verwenden.Redis wird von Microsoft Azure verwendet, so dass es eine gute Unterstützung von Microsoft und eine Integration in ASP.NET bietet, aber Sie können jede NoSQL-Lösung auswählen.

+0

asp.net verwendet einen Thread pro (schreibbare) Sitzung, die die Benutzer auf jeweils eine Anfrage beschränkt. Das möchte ich verhindern. Können Sie angeben, warum meine Daten nicht zur Sitzung gehören (Dropdown-Werte zum Beispiel)? – JoeJoe87577

+0

Das ist einfach nicht korrekt. Ich bin mir nicht sicher, wo Sie diese Informationen haben. Soweit, warum sollten Sie keine Sitzung für diese Daten verwenden, im Allgemeinen sollten Sie Sitzungen für sehr wenig, Zeitraum verwenden. Wenn Daten zu einem bestimmten Benutzer gehören, können Sie sie später einfach erneut vom Benutzer abrufen. Sitzungen sollten nur für Daten verwendet werden, die für anonyme Benutzer spezifisch sind, die * tatsächlich * zwischen Anträgen bestehen müssen. So etwas wie Dropdown-Optionen überprüft keines dieser Felder. Vielleicht möchten Sie es * cachen *, um einen Rundlauf zur Datenbank zu vermeiden, aber es gehört nicht in die Sitzung. –

+0

@ChrisPratt - Es ist nicht korrekt zu sagen, dass die Verwendung von ObjectCache nicht auf mehrere Prozesse skaliert werden - Sie könnten ein [verteiltes ObjektCache] (http://stackoverflow.com/questions/14646658/i-am-looking-for) verwenden -a-verteilte-data-object-cache-für-meine-asp-net-mvc-app), um das zu handhaben. Aber ist es den zusätzlichen Aufwand wert, wenn Sie den Out-of-Process-Sitzungsstatus oder etwas wie Redis verwenden? Wahrscheinlich nicht. – NightOwl888

Verwandte Themen