Ho un'applicazione Web che deve utilizzare una cache dell'applicazione per archiviare i dati (a causa dell'elevato sovraccarico di ottenere tali dati su una richiesta per richiesta). Vedi post precedente a https://stackoverflow.com/a/16961962/236860Rilascio di un mutex
Questo approccio sembra funzionare bene, ma sto vedendo i seguenti errori occasionali errori del sito web:
System.ApplicationException: Object synchronization method was called from an
unsynchronized block of code.
at System.Threading.Mutex.ReleaseMutex()
at InboxInsight.Web.Web_Controls.Twitter.TwitterFeed.GetTwitterData(HttpContext context)
at InboxInsight.Web.Web_Controls.Twitter.TwitterFeed.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Per riferimento, ecco il blocco di codice:
public string GetData(HttpContext context)
{
var cache = context.Cache;
Mutex mutex = null;
string data = (string)cache[CacheKey];
// Start check to see if available on cache
if (data == null)
{
try
{
// Lock base on resource key
// (note that not all chars are valid for name)
mutex = new Mutex(true, CacheKey);
// Wait until it is safe to enter (someone else might already be
// doing this), but also add 30 seconds max.
mutex.WaitOne(30000);
// Now let's see if some one else has added it...
data = (string)cache[CacheKey];
// They did, so send it...
if (data != null)
{
return data;
}
// Still not there, so now is the time to look for it!
data = GetSlowFeed(context);
cache.Remove(CacheKey);
cache.Add(CacheKey, data, null, GetExpiryDate(),
TimeSpan.Zero, CacheItemPriority.Normal, null);
}
finally
{
// Release the Mutex.
if (mutex != null)
{
mutex.ReleaseMutex();
}
}
}
return data;
}
Da quello che ho cercato, suggerisce che questo problema è causato da un thread di processo che tenta di rilasciare un Mutex che non ha creato, ma non capisco come ciò potrebbe accadere.
Qualcuno può suggerire come posso ri-strutturare il codice per evitare questo problema?
Ho aggiunto un commento alla tua altra domanda. Tuttavia è probabilmente appropriato anche qui. Esistono provider di cache per asp.net. AppFabric è uno, Memcached è un altro. Entrambi sono molto bravi in quello che fanno. Al punto che non mi preoccuperei di arrotolare il mio. – NotMe
Ciao Chris, grazie per il suggerimento. Ora ho esaminato AppFabric e Memcached, ma non sembrano adatti alla mia applicazione poiché è in esecuzione in un ambiente di hosting condiviso. Come applicazioni di cache distribuita, credo che entrambi debbano essere installati a livello di server/OS che, sfortunatamente, precludono il loro uso in questa applicazione. – Neilski