2010-10-28 49 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); 
     } 
    } 

我的問題:

  • 訪問或刪除緩存項目是否需要一定級別的權限?我GOOGLE了這一點,但沒有找到任何具體的東西(甚至在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: 我們剛剛更新到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

我們終於想出了這個問題的答案。問題與模擬有關(我們在web.config中打開了它)以及我們使用單例訪問XRM的事實。顯然,當多個用戶試圖通過我們的軟件同時運行CRM查詢時,單身人士會在其用戶環境下與CRM建立連接。顯然,在發生這種情況時,查詢結果的緩存由該用戶上下文「擁有」。當另一個用戶試圖同時運行一個查詢時,他們會收到一個401狀態碼。

解決方案最終被轉化爲模仿並做了一些小的重構,這樣我們就不再需要它了。我想我們可以改爲允許多個CRM實例 - 儘管我們故意不會出於性能原因這麼做。

我希望這可以幫助任何可能會看到這些時髦錯誤的人。

0

我無法想象的是,異常實際上是綁在Cache.Remove電話。

只是一個猜測,但是這個異常是否與CacheItemRemovedCallback相關,而不是實際的刪除步驟(不確定回調是否在同一個線程中同步執行)?

你能發佈異常的完整堆棧跟蹤嗎?

+0

我剛剛添加了堆棧跟蹤。 – jslatts 2010-11-01 16:19:42