У меня есть приложение, которое хранит большие списки в кеше. Чтобы не допустить одновременного заполнения этого кэша несколькими пользователями, я использую Mutex. Тем не менее, я получаю случайные ошибки:
System.Threading.AbandonedMutexException: ожидание завершено из-за брошенного мьютекса.
Вы могли бы утверждать, что я забыл выпустить Mutex, но выпуск находится в блоке finally, поэтому он всегда должен выпускать его. Как приведенный ниже код может вызвать исключение AbandonedMutexException? 'Mutex.ReleaseMutex' должен запускаться всегда.
public static List<Objects.SearchListItem> GetActiveCwPropertyListItemsByCwPropertyAndCulture(CwProperty cwProperty, string cultureCode)
{
var cacheKey = "GetActiveCwPropertyListItemsByCwPropertyAndCulture_" + cwProperty.Guid + "_" + cultureCode;
var mutex = new Mutex(true, cacheKey);
mutex.WaitOne();
try
{
var cachedValue = HttpRuntime.Cache[cacheKey];
if (cachedValue != null) return (List<Objects.SearchListItem>)cachedValue;
var value = new List<Objects.SearchListItem>();
var dr = new CwDbAccess(System.Data.CommandType.StoredProcedure, "CwPropertyListItemPart_LoadByCwProperty");
try
{
dr.ExecuteReader();
while (dr.MyReader.Read())
{
value.Add(new Objects.SearchListItem
{
Name = Utils.ProperCase(dr.MyReader["Name"].ToString()),
Key = dr.MyReader["CwPropertyListItem_Guid"].ToString(),
IsAlias = false
});
}
}
catch (Exception ex)
{
CwLogging.LogException("Caching.ListItems.GetActiveCwPropertyListItemsByCwPropertyAndCulture", ex, ExceptionLevel.Urgent);
}
finally
{
dr.Close();
}
var keys = new List<string>();
AddDependency("CwSiteClusterKey_" + cwProperty.CachedCwEntity.CwSiteClusterGuid, keys);
AddDependency("CwPropertyKey_" + cwProperty.Guid, keys);
HttpRuntime.Cache.Insert(cacheKey, value, new CacheDependency(null, keys.ToArray()), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
return value;
}
catch
{
throw;
}
finally
{
mutex.ReleaseMutex();
}
}
Полная трассировка стека:
System.Threading.AbandonedMutexException: ожидание завершено из-за оставленного мьютекса.
в System.Threading.WaitHandle.ThrowAbandonedMutexException ()
в System.Threading.WaitHandle.InternalWaitOne (SafeHandle waitableSafeHandle, Int64 миллисекундыTimeout, логическое значение hasThreadAffinity, логическое значение exitContext)
в System.Threading.WaitHandle.WaitOne (Int32 миллисекундTimeout, логическое значение exitContext)
в Common.Caching.ListItems.GetActiveCwPropertyListItemsByCwPropertyAndCulture (CwProperty cwProperty, String cultureCode)
в Model.SearchFacet.GetAllSearchListItems (CwContext cwContext)
в Common.Search.SqlFacets.RetrieveSqlFacetsByGroup (CwEntity cwEntity, NameValueCollection selectedRequestForm, SqlFacetsContainer sqlFacets, группы SearchFacetGroupCollection, SearchTemplate searchTemplate, CwConxtxtw)
в Common.Search.SqlFacets.RetrieveSqlFacets (CwEntity cwEntity, NameValueCollection StoreRequestForm, CwContext cwContext, SearchResultViewType searchResultViewType)
в Common.Caching.SqlFacets.GetSqlFacets (Строковый хеш, NameValueCollection selectedRequestForm, CwEntity cwEntity, CwContext cwContext, SearchResultViewType searchResultViewType)
в Compareware_WebApp.Ui.Pages.SearchPage.AppendSearchAndResults (StringBuilder sb) в C: \ Projects \ Compareware \ Compareware.WebApp \ Ui \ Pages \ SearchPage.cs: строка 454
в Compareware_WebApp.Ui.Pages.SearchPage.get_MainContent () в C: \ Projects \ Compareware \ Compareware.WebApp \ Ui \ Pages \ SearchPage.cs: строка 310
в ASP.default_aspx .__ RenderContent2 (HtmlTextWriter __w, управляющий параметрContainer)
в System.Web.UI.Control.RenderChildrenInternal (автор HtmlTextWriter, дети ICollection)
в System.Web.UI.Control.RenderControlInternal (средство записи HtmlTextWriter, адаптер ControlAdapter)
в System.Web.UI.Control.RenderChildrenInternal (автор HtmlTextWriter, дети ICollection)
в System.Web.UI.Control.RenderControlInternal (средство записи HtmlTextWriter, адаптер ControlAdapter)
на ASP.masters_site_master .__ RenderForm1 (HtmlTextWriter __w, управляющий параметрContainer)
в System.Web.UI.Control.RenderChildrenInternal (автор HtmlTextWriter, дети ICollection)
в System.Web.UI.HtmlControls.HtmlForm.RenderChildren (писатель HtmlTextWriter)
в System.Web.UI.HtmlControls.HtmlContainerControl.Render (писатель HtmlTextWriter)
в System.Web.UI.Control.RenderControlInternal (средство записи HtmlTextWriter, адаптер ControlAdapter)
в System.Web.UI.HtmlControls.HtmlForm.RenderControl (писатель HtmlTextWriter)
в ASP.masters_site_master .__ RenderBody (HtmlTextWriter __w, управляющий параметрContainer)
в System.Web.UI.Control.RenderChildrenInternal (автор HtmlTextWriter, дети ICollection)
в System.Web.UI.HtmlControls.HtmlContainerControl.Render (писатель HtmlTextWriter)
в System.Web.UI.Control.RenderControlInternal (средство записи HtmlTextWriter, адаптер ControlAdapter)
на ASP.masters_site_master .__ Render__control1 (HtmlTextWriter __w, управляющий параметрContainer)
в System.Web.UI.Control.RenderChildrenInternal (автор HtmlTextWriter, дети ICollection)
в System.Web.UI.Control.RenderControlInternal (средство записи HtmlTextWriter, адаптер ControlAdapter)
в System.Web.UI.Control.RenderChildrenInternal (автор HtmlTextWriter, дети ICollection)в System.Web.UI.Control.RenderControlInternal (средство записи HtmlTextWriter, адаптер ControlAdapter)
в System.Web.UI.Control.RenderChildrenInternal (автор HtmlTextWriter, дети ICollection)
в System.Web.UI.Page.Render (писатель HtmlTextWriter)
в System.Web.UI.Control.RenderControlInternal (средство записи HtmlTextWriter, адаптер ControlAdapter)
в System.Web.UI.Page.ProcessRequestMain (логическое значение includeStagesBeforeAsyncPoint, логическое значение includeStagesAfterAsyncPoint)