2008-11-06 6 views
12

Ich bemerkte, dass die ASP.NET-Cache-Elemente überprüft werden (und möglicherweise entfernt) alle 20 Sekunden (und seltsamerweise jedes Mal bei HH: MM: 00, HH: MM: 20 und HH: MM: 40). Ich habe ungefähr 15 Minuten damit verbracht, herauszufinden, wie ich diesen Parameter ohne Erfolg ändern kann. Ich habe auch versucht die folgenden in web.config zu setzen, aber es half nicht:Ändern der Häufigkeit des Ablaufs von ASP.NET-Cache-Elementen?

<cache privateBytesPollTime="00:00:05" /> 

Ich bin nicht zu tun, etwas verrückt versucht, aber es wäre schön, wenn es beispielsweise 5 Sekunden statt 20 oder mindestens 10 für meine Bewerbung.

Antwort

19

Wenn Sie mit Reflector herumstochern, wird angezeigt, dass das Intervall fest codiert ist. Ablauf wird durch eine interne CacheExpires Klasse behandelt, deren statischen Konstruktor enthält

_tsPerBucket = new TimeSpan(0, 0, 20); 

_tsPerBucketreadonly ist, so kann es keine Konfigurationseinstellung sein, die es später modifiziert.

Der Zeitgeber, der die Prüfung für abgelaufene Elemente auslösen wird dann in CacheExpires.EnableExpirationTimer() einstellen ...

DateTime utcNow = DateTime.UtcNow; 
TimeSpan span = _tsPerBucket - new TimeSpan(utcNow.Ticks % _tsPerBucket.Ticks); 
this._timer = new Timer(new TimerCallback(this.TimerCallback), null, 
    span.Ticks/0x2710L, _tsPerBucket.Ticks/0x2710L); 

Die Berechnung der span stellt sicher, dass der Zeitgeber ausgelöst genau auf: 00: 20: 40 Sekunden obwohl ich keinen Grund sehe, mich darum zu kümmern. Die Methode, die der Timer aufruft, ist internal, also glaube ich nicht, dass es irgendeinen Weg gibt, einen eigenen Timer einzurichten, um ihn öfter anzurufen (Reflexion ignorierend).

Die gute Nachricht ist jedoch, dass Sie eigentlich keinen Grund haben sollten, sich um das Intervall zu kümmern. prüft, ob das Element nicht abgelaufen ist, und wenn dies der Fall ist, entfernt es das Objekt sofort aus dem Cache und gibt null zurück. Daher erhalten Sie nie ein abgelaufenes Objekt aus dem Cache, obwohl abgelaufene Elemente bis zu 20 Sekunden im Cache bleiben können.

2

Gemäß der documentation, privateBytesPollTime ist für "Worker-Prozess Speicherverbrauch" und der Standardwert ist 1 Sekunde. Ich glaube nicht, dass es sich um die Entfernung von Cache-Objekten handelt.

Ich habe Ihre Ergebnisse mithilfe eines Rückrufs zum Entfernen von Elementen bestätigt. Es sieht so aus, als ob Elemente am Ende der Minute, 20 und 40 Sekunden entfernt werden. Dies deutet darauf hin, dass ein Objekt bis zu 20 Sekunden nach dem für sie festgelegten AbsoluteExpiration-Wert im Cache verbleiben kann. Ich konnte keine Dokumentation finden, die angibt, ob das 20-Sekunden-Abfrageintervall geändert werden könnte.

0

Für was es wert ist, können Sie einen Blick auf die question I have asked werfen: Ich habe dort einen Beispielcode, der beweist, dass, obwohl ich absolute expiration time von 10 Sekunden eingestellt habe, der Update-Rückruf alle 40 Sekunden stattfindet.

2

Verrückt, aber Arbeitslösung (alle Schritte sind erforderlich):

// New value for cache expiration cycle 
// System.Web.Caching.CacheExpires._tsPerBucket; 
// Set 1 seconds instead of 20sec 
const string assembly = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; 
var type = Type.GetType("System.Web.Caching.CacheExpires, " + assembly, true, true); 
var field = type.GetField("_tsPerBucket", BindingFlags.Static | BindingFlags.NonPublic); 
field.SetValue(null, TimeSpan.FromSeconds(1)); 

// Recreate cache 
// HttpRuntime._theRuntime._cacheInternal = null; 
// HttpRuntime._theRuntime._cachePublic = null; 
type = typeof (HttpRuntime); 
field = type.GetField("_theRuntime", BindingFlags.Static | BindingFlags.NonPublic); 
var runtime = field.GetValue(null); 
field = type.GetField("_cachePublic", BindingFlags.NonPublic | BindingFlags.Instance); 
field.SetValue(runtime, null); 
field = type.GetField("_cacheInternal", BindingFlags.NonPublic | BindingFlags.Instance); 
field.SetValue(runtime, null); 
Verwandte Themen