ASP.NET UnauthorizedAccessException при доступе к элементу из кэша - PullRequest
1 голос
/ 28 октября 2010

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

Вот ошибка UnceptionhorizedAccessException:

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);
        }
    }

Мои вопросы:

  • Требуется ли какой-либо уровень разрешения для доступа илиудалить элементы кэша?Я гуглил это, но не нашел ничего конкретного (даже в 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

ОБНОВЛЕНИЕ2: Мы только что обновились до версии 4.0.13 SDK, чтобы отключитькэширование (на самом деле я мог заставить его работать, только установив продолжительность в 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 ]

2 голосов
/ 17 ноября 2010

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

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

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

0 голосов
/ 29 октября 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...