2010-10-28 2 views
1

У нас есть код, который иногда вычищал определенные ключи в кеше ASP.NET, чтобы быть уверенным, что мы обновляем данные из нашей системы Dynamics CRM. Кажется, что он отлично работает большую часть времени, однако мы получаем прерывистые исключения при перезагрузке страниц, которые, как я подозреваю, связаны с этой принудительной промывкой кеша.ASP.NET UnauthorizedAccessException при доступе к элементу из кеша

Здесь ошибка в UnauthorizedAccessException:

Access to the path 'appDomain=/LM/W3SVC/1/ROOT-1-129326029589946795:key=Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:Query=953227368' is denied. 

В случае это полезно, вот как я промывке элементы кэша:

private void Flush() 
    { 
     IDictionaryEnumerator cacheEnum = this.HttpContext.Cache.GetEnumerator(); 
     while (cacheEnum.MoveNext()) 
     { 
      var key = cacheEnum.Key.ToString(); 

      if (key.StartsWith("Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:Query")) 
       System.Web.HttpContext.Current.Cache.Remove(key); 
     } 
    } 

Мои вопросы:

  • Требуется ли какой-либо уровень разрешения для доступа или удаления элементов кэша? Я googled это, но не нашел ничего конкретного (даже в MSDN).
  • Вы уже видели эту ошибку? Как вы это разрешили?

ОБНОВЛЕНИЕ: вот стоп-трасса.

Stacktrace: 
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
at System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(Object userData) 
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) 
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity) 
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Lock(String key, Int32 millisecondsTimeout, Action`1 action) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Int32 millisecondsTimeout, Func`2 loadFromCache, Func`2 loadFromService) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Func`2 loadFromCache, Func`2 loadFromService, Action`2 addToCache) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.InnerExecute[TRequest,TResponse,TResult](TRequest request, Func`2 execute, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute[T](MetadataServiceRequest request, Func`5 execute, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute[T](MetadataServiceRequest request, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute(Object request) 
at Microsoft.Xrm.Client.Services.IOrganizationServiceExtensions.RetrieveAllEntities(IOrganizationService service, MetadataItems metadataItems, Boolean retrieveAsIfPublished) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.GetId(DynamicEntity entity) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__48.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__41.MoveNext() 
at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__2b.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__13.MoveNext() 
at System.Linq.Enumerable.<DistinctIterator>d__81`1.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.GetCachePolicy(Object query, Object result) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.Insert(String key, Object query, Object result) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.<>c__DisplayClass5`1.<Get>b__4(String k) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.<>c__DisplayClass2`1.<Get>b__0(Mutex _) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Lock(String key, Int32 millisecondsTimeout, Action`1 action) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Int32 millisecondsTimeout, Func`2 loadFromCache, Func`2 loadFromService) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Func`2 loadFromCache, Func`2 loadFromService, Action`2 addToCache) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.InnerExecute[TRequest,TResponse,TResult](TRequest request, Func`2 execute, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute[T](Request request, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.RetrieveMultiple(QueryBase query) 
at Microsoft.Xrm.Client.Services.IOrganizationServiceExtensions.Using[T](Func`1 create, Func`2 action) 
at Microsoft.Xrm.Client.Linq.CrmQueryProvider.Execute[TElement](QueryExpression qe, LambdaExpression projection, Delegate postMethodCall, LambdaExpression filter, Type entityType) 
at Microsoft.Xrm.Client.Linq.CrmQueryProvider.Execute[TElement](Expression expression) 
at Microsoft.Xrm.Client.Linq.QueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression) 
at System.Linq.Queryable.Single[TSource](IQueryable`1 source) 
at FrontOfficeApp.Controllers.BillingController.GetBillingInstitutions(Requisition req) 
at FrontOfficeApp.Controllers.BillingController.InstitutionalBillPartial(Int32 requisitionId) 
at lambda_method(Closure , ControllerBase , Object[]) 
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a() 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 
at System.Web.Mvc.Controller.ExecuteCore() 
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() 
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() 
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Message=Access to the path 'appDomain=/LM/W3SVC/1/ROOT-1-119328537521157948:key=Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:Query=913126368' is denied. 
Data=System.Collections.ListDictionaryInternal 

UPDATE2: Мы просто обновлен до версии SDK 4.0.13 для того, чтобы отключить кэширование (на самом деле я мог получить только его на работу, установив длительность на 1 секунду, см. Ниже) Это позволяет обойти вопрос о CRM необходимости промывать, но мы по-прежнему получать ошибки кэширования в нашей среде, хотя они выглядят немного по-другому прямо сейчас:

Message=Access to the path 'appDomain=/LM/W3SVC/1/ROOT-1-129341239247458264:key=Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:User=00000000-0000-0000-0000-000000000000,00000000-0000-0000-0000-000000000000:Query=923237368' is denied. 
Data=System.Collections.ListDictionaryInternal 

Для того, что стоит, контекст Конфигурация, которую я использую, приведен ниже. Я добавляю щедрость к этому вопросу в качестве последней попытки канавы.

<microsoft.xrm.client> 
    <contexts default="Crm"> 
     <add name="Crm" type="CRM.XrmDataContext" serviceName="Default" /> 
    </contexts> 
    <services default="Default"> 
     <add name="Default" cacheProviderName="Default" /> 
    </services> 
    <cache defaultProvider="Default"> 
     <providers> 
      <add name="Default" 
       type="Microsoft.Xrm.Client.Caching.InMemoryCacheProvider, Microsoft.Xrm.Client" duration="00:00:01" /> 
     </providers> 
    </cache> 
</microsoft.xrm.client> 

ответ

2

Наконец-то мы выяснили ответ на этот вопрос. Проблема была связана с олицетворением (мы включили его в web.config) и тем фактом, что мы обращались к XRM с использованием синглета. По-видимому, когда несколько пользователей пытались запускать одновременные CRM-запросы через наше программное обеспечение, singleton будет подключаться к CRM под их пользовательским контекстом. По-видимому, пока это происходит, кеш для результатов запроса «принадлежит» этим пользовательским контекстом. Когда другой пользователь попытался выполнить запрос в одно и то же время, он получит код состояния 401.

Исправление закончилось тем, что оно превратилось в олицетворение и сделало небольшой рефакторинг, чтобы он больше не нуждался в нем. Я предполагаю, что мы могли бы позволить несколько экземпляров CRM, хотя мы намеренно не делаем этого по соображениям производительности.

Я надеюсь, что это поможет всем, кто может видеть эти фанковые ошибки.

0

Я не могу себе представить, что исключение на самом деле связано с Cache.Remove вызова.

Только предположение, но возможно, что исключение связано с CacheItemRemovedCallback и не фактический шаг удаления (не уверен, если обратный вызов выполняется синхронно в том же потоке)?

Можете ли вы опубликовать полную трассировку стека для исключения?

+0

Я просто добавил stacktrace. – jslatts

Смежные вопросы