Why am I getting "Invalid Internal state" reflection exception with Castle DynamicProxy? - asp.net

We added DynamicProxy to our ASP.NET web app a couple of weeks ago. The code ran fine in dev and QA, but when we pushed to production, we got the following exception (top of stack trace only):
[ArgumentNullException: Invalid internal state.]
System.Reflection.Emit.TypeBuilder._InternalSetMethodIL(Int32 methodHandle, Boolean isInitLocals, Byte[] body, Byte[] LocalSig, Int32 sigLength, Int32 maxStackSize, Int32 numExceptions, __ExceptionInstance[] exceptions, Int32[] tokenFixups, Int32[] rvaFixups, Module module) +0
System.Reflection.Emit.TypeBuilder.InternalSetMethodIL(Int32 methodHandle, Boolean isInitLocals, Byte[] body, Byte[] LocalSig, Int32 sigLength, Int32 maxStackSize, Int32 numExceptions, __ExceptionInstance[] exceptions, Int32[] tokenFixups, Int32[] rvaFixups, Module module) +56
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() +1033
System.Reflection.Emit.TypeBuilder.CreateType() +99
Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder type) +72
Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() +96
Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope) +854
Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options) +834
Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) +133
Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) +52
Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) +308
Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors) +48
Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors) +44
It worked fine when we first pushed the code, and an IIS reset fixed it, so I'm assuming it's thread related, but I couldn't find anything on the interwebs regarding best practices for thread-safety proxy generation. Suggestions?
UPDATE: After reading some more on the issue, especially here, I realized one potential issue -- namely that I had not overwritten Equals/GetHashCode for the implementation of IProxyGenerationHook I had written, which would prevent DynamicProxy from caching it's types. As I can find next to nothing on the exception I saw in general let alone related to DP, I'm gonna assume that it was the lack of caching of types caused by my omission that was the root cause of the problem, though I'd love a confirmation.
For the record, my object creation is pretty vanilla:
private T CreateProxy(MyArgs args)
{
var options = new ProxyGenerationOptions(new MyMethodSelector());
options.AddMixinInstance(new MyMixin());
return Generator.CreateClassProxy(
TargetType,
options,
new[] { new MyInterceptor(args) }) as T;
}

actually DynamicProxy is thread safe so it is quite unlikely it is concurrency related.
First of all, which version of DynamicProxy are you using?
Are you able to reproduce the issue in isolation, outside of IIS?
This issue was reported two years ago, but it was fixed. Please make sure you have the latest version.

Related

PostgreSQL to add type Nvarchar?

Is there any suggestion for PostgreSQL to add type Nvarchar?
This is the error that I am getting:
Npgsql.PostgresException (0x80004005): 42704: type "nvarchar" does not exist
at Npgsql.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|194_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult()
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteNonQuery()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Exception data:
Severity: ERROR
SqlState: 42704
MessageText: type "nvarchar" does not exist
Position: 94
File: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\parser\parse_type.c
Line: 274
Routine: typenameType
42704: type "nvarchar" does not exist
Thank you.
"National" string data types are a vestige from the dim and distant past when people still used single-byte encodings like ISO 8859-1 or Windows-1252.
Nowadays we store data using UNICODE encodings, in the case of PostgreSQL, UTF-8. Since you can store any character that way, there is no need for a special data type.
This error occured to me when my last migration (which the update-database command uses) was not for a PostgreSQL connection.
You can try this:
create a new migration with add-migration <name>
clear the database with update-database 0
apply the newly created migration on the database with update-database
In my case, first I was using SQL Server as DB and changed to PostgreSQL. Old migrations were caused the problem type "nvarchar" does not exist. Deleted old migrations and created new migration, updated everything worked fine.

Null buffer error

I've just noticed that when running an application I periodically get an error message.
Server Error in '/' Application.
Buffer cannot be null.
Parameter name: buffer
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentNullException: Buffer cannot be null.
Parameter name: buffer
Stack trace:
[ArgumentNullException: Buffer cannot be null.
Parameter name: buffer]
System.IO.MemoryStream..ctor(Byte[] buffer, Boolean writable) +12627669
MemcachedProviders.Session.Common.Deserialize(HttpContext context, Byte[] serializedItems, Int32 timeout) +47
MemcachedProviders.Session.Db.SQLDbOperations.GetItem(String strSessionId, String strApplicationName, Int32 iTime, HttpContext context, Boolean lockRecord, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actionFlags) +1221
MemcachedProviders.Session.SessionStateProvider.GetItemExclusive(HttpContext context, String id, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actions) +1069
System.Web.SessionState.SessionStateModule.GetSessionStateItem() +178
System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(Object state) +299
[HttpException (0x80004005): Exception of type 'System.Web.HttpException' was thrown.]
System.Web.SessionState.SessionStateModule.EndAcquireState(IAsyncResult ar) +11513726
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +107
Our application uses Enyim memcached and MemcachedProviders and runs in a load balanced environment.
The application does alot of managing of PDF reports and compiling of responses then generating a final report pdf. So we use streams quite a bit.
This problem only appears to affect our management application as we also expose a webservice and I never get the error when looking at the service definition and WSDL.
From looking at the session table in the DB I can see that they are being created but, many of them have null in the SessionItems field and the locked flag set to 1.
The data time stamps seem to correlate to the null buffer error occurances.
Is this a case of a buffer set incorrectly or maxing out?

Convention based binding in Ninject 3.0

I'm trying to setup Ninject on my new project and I want to scan assembilies using convetions so that
IFoo
will automatically resolve to
IBar
All the samples and documentation describes using this approach
kernel.Scan(...)
while the Ninject 3 Kernel seems to use .Load instead. If I'm using Load for scanning then how do I configure scanning with conventions?
Edit
I was able to get it working using: https://github.com/ninject/ninject.extensions.conventions/wiki/What-is-configuration-by-convention
However, now I can't get my modules to load. I'm using the code below and getting the error below.
IKernel kernel = new StandardKernel();
kernel.Bind(x => x
.FromAssembliesMatching("Crt.*.dll")
.SelectAllTypes()
.BindAllInterfaces()
);
kernel.Load("*.dll");
return kernel;
Error:
Ninject.ActivationException was unhandled
Message=Error activating ITrainingEngine
More than one matching bindings are available.
Activation path:
1) Request for ITrainingEngine
Suggestions:
1) Ensure that you have defined a binding for ITrainingEngine only once.
Source=Ninject
StackTrace:
at Ninject.KernelBase.Resolve(IRequest request) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 380
at Ninject.ResolutionExtensions.GetResolutionIterator(IResolutionRoot root, Type service, Func`2 constraint, IEnumerable`1 parameters, Boolean isOptional, Boolean isUnique) in c:\Projects\Ninject\ninject\src\Ninject\Syntax\ResolutionExtensions.cs:line 263
at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters) in c:\Projects\Ninject\ninject\src\Ninject\Syntax\ResolutionExtensions.cs:line 37
at Crt.BlackBox.Train.Program.Run() in C:\code\Crimson\CRT\readmission\src\Crt.BlackBox\Crt.BlackBox.Train\Program.cs:line 54
at Crt.BlackBox.Train.Program.Main(String[] args) in C:\code\Crimson\CRT\readmission\src\Crt.BlackBox\Crt.BlackBox.Train\Program.cs:line 24
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Use SelectAllClasses instead of SelectAllTypes

Can I use SQL Server CE in a medium trust environment by just deploying the DLLs

I've written an ASP.NET 4.0 application that is using a SQL Server CE 4.0 database. This is all working on my development environment using Medium Trust (same trust config as the hoster). On this machine, I've gone through the install process (downloaded and installed the MSI). I'm now trying to deploy this solution to my web hoster.
The code that is running is (this is a straight out copy of the Altairis Membership Provider:
using (HostingEnvironment.Impersonate())
using (var db = this.connectionString.CreateDbConnection())
using (var cmd = this.CreateDbCommand("SELECT PasswordHash, PasswordSalt FROM $Users WHERE UserName = #UserName AND IsApproved = 1", db))
{
cmd.AddParameterWithValue("#UserName", username);
db.Open();
// Validate password
using (var r = cmd.ExecuteReader()) { .. snip.. }
}
In the instance above, db is DbConnection, and cmd is DbCommand
I'm getting the following error:
[InvalidOperationException: Cannot perform CAS Asserts in Security Transparent methods]
System.Security.CodeAccessSecurityEngine.CheckNReturnSO(PermissionToken
permToken, CodeAccessPermission demand, StackCrawlMark& stackMark,
Int32 create) +0
System.Security.CodeAccessSecurityEngine.Assert(CodeAccessPermission
cap, StackCrawlMark& stackMark) +61
System.Security.CodeAccessPermission.Assert() +28
System.Data.SqlServerCe.KillBitHelper.GetKillBit() +231
System.Data.SqlServerCe.KillBitHelper..cctor() +56
[TypeInitializationException: The type initializer for 'System.Data.SqlServerCe.KillBitHelper' threw an exception.]
System.Data.SqlServerCe.KillBitHelper.ThrowIfKillBitIsSet() +0
System.Data.SqlServerCe.SqlCeProviderFactory..cctor() +41
[TypeInitializationException: The type initializer for 'System.Data.SqlServerCe.SqlCeProviderFactory' threw an exception.]
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeFieldHandle.GetValue(RtFieldInfo field, Object instance, RuntimeType fieldType, RuntimeType declaringType, Boolean&
domainInitialized) +0
System.Reflection.RtFieldInfo.InternalGetValue(Object obj, Boolean doVisibilityCheck, Boolean doCheckConsistency) +180
System.Reflection.RtFieldInfo.GetValue(Object obj) +8
System.Data.Common.DbProviderFactories.GetFactory(DataRow providerRow) +232
System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName) +88
Altairis.Web.Security.DatabaseExtensionMethods.CreateDbConnection(ConnectionStringSettings
settings) in DatabaseExtensionMethods.cs:19
Altairis.Web.Security.TableMembershipProvider.ValidateUser(String
username, String password) in TableMembershipProvider.cs:361
I've used a decompiler to look through the code, and it seems that the internals of SQL Server CE are looking for a registry entry and then trying to do a code Assert().
Is it possible to use SQL Server CE 4.0 in a partial trust environment, by just \bin deploying the DLL ??
Yes, provided your hoster allows it - it is allowed by default in ASP.NET 4.0. Make sure you use assembly version 4.0.0.0 (and not 4.0.0.1). Read more here: http://erikej.blogspot.com/2011/10/sql-server-compact-40-under-aspnet.html

ASP.NET UnauthorizedAccessException when accessing item from cache

We have some code that occasionally flushed out certain keys in the ASP.NET cache in order to make sure that we are getting up to date data from our Dynamics CRM system. It seems to work fine most of the time, however we are getting intermittent exceptions on page reloads that I suspect is related to this forced cache flushing.
Here is the error in the UnauthorizedAccessException:
Access to the path 'appDomain=/LM/W3SVC/1/ROOT-1-129326029589946795:key=Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:Query=953227368' is denied.
In case it is helpful, here is how I am flushing the cache items:
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);
}
}
My questions:
Is there some level of permission required to access or remove cache items? I googled this but did not find anything specific (even in MSDN).
Have you seen this error before? How did you resolve it?
UPDATE: here is the stacktrace.
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:
We just updated to the 4.0.13 version of the SDK in order to turn off caching (actually I could only get it to work by setting the duration to 1 second, see below). This allows us to get around the issue of CRM needing to be flushed, but we are still getting the caching errors in our environment, although they look a little different now:
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
For what is is worth, the context configuration I am using is below. I am adding a bounty to this question as a last ditch attempt.
<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>
We finally figured out the answer to this issue. The problem was related to impersonation (we had it turned on in the web.config) and the fact that we were accessing XRM using a singleton. Apparently, when multiple users tried to run simultaneous CRM queries through our software, the singleton would make the connection to CRM under their user context. Apparently while this is happening, the cache for the query results are "owned" by that user context. When another user tried to run a query at the same time, they would receive a 401 status code.
The fix ended up being to turn of impersonation and do some minor refactoring so that we did not need it anymore. I imagine we could instead have allowed multiple CRM instances--though we intentionally don't do that for performance reasons.
I hope this helps anyone else who might be seeing these funky errors.
I can't imagine that the exception is actually tied to the Cache.Remove call.
Just a guess, but is it possible that the exception is related to the CacheItemRemovedCallback and not the actual removal step (not sure if the call-back is executed synchronously on the same thread)?
Can you post the full stack trace for the exception?

Resources