Ich verwende die folgende Service-Methode, um das Ergebnis einer Abfrage cachen:MVC 5 HttpContext.Current.Cache Methode schlägt fehl, wenn du von zwei Threads zur gleichen Zeit getroffen
private readonly CoreDbContext _dbContext;
public EcommerceProductService()
{
_dbContext = GetDbContext();
}
public IEnumerable<EcommerceProduct> GetAllCached()
{
var cachedResult = HttpContext.Current.Cache["EcommerceProductService.GetAllCached"] as IEnumerable<EcommerceProduct>;
if (cachedResult == null)
{
var result = _dbContext.EcommerceProducts.ToList();
HttpContext.Current.Cache.Insert("EcommerceProductService.GetAllCached", result);
return result;
}
return cachedResult;
}
In einer bestimmten Seite , diese Methode wird gleichzeitig von 2 Threads aufgerufen (weil ich die gesamte Sammlung von Produkten zweimal, aber mit verschiedenen Filtern anzeigen muss).
Seltsam, beim ersten Start der Anwendung nur einer der Threads "gewinnt" und erhält die Liste der Produkte, während der andere Null empfängt. Wenn ich die Seite aktualisiere, beginnen beide gut zu funktionieren (weil sie zu diesem Zeitpunkt das Ergebnis aus dem Cache holen), aber das erste Mal, wenn es das eine oder das andere Mal ist, funktionieren beide nie.
Ich habe auch versucht, den gesamten Code in eine Lock-Anweisung zu wickeln, aber es hat nichts geändert. Was vermisse ich?
private readonly CoreDbContext _dbContext;
private static readonly object Locker = new object();
public EcommerceProductService()
{
_dbContext = GetDbContext();
}
public IEnumerable<EcommerceProduct> GetAllCached()
{
lock (Locker)
{
var cachedResult = HttpContext.Current.Cache["EcommerceProductService.GetAllCached"] as IEnumerable<EcommerceProduct>;
if (cachedResult == null)
{
var result = _dbContext.EcommerceProducts.ToList();
HttpContext.Current.Cache.Insert("EcommerceProductService.GetAllCached", result);
return result;
}
return cachedResult;
}
}
Wie Sie aus meinem Code sehen können, habe ich genau das getan. Der Konstruktor initialisiert den Wert für new object(). – tocqueville
Das ist das Problem. In jeder neuen Instanz ändern Sie den Wert des statischen Objekts. Entfernen Sie den gesamten Code aus dem Konstruktor. Lasse nur die Deklaration wie ich sie habe. – kagelos
Fertig, aber das Problem bleibt bestehen. Sehe meine aktualisierte Frage. Vielleicht ist das Schloss überhaupt nicht die Antwort. Das Problem könnte woanders sein. – tocqueville