简体   繁体   English

Appfabric DataCache反序列化问题在Get上

[英]Appfabric DataCache Deserialization Issue on Get

We are having a strange problem with the Appfabric DataCache. Appfabric DataCache存在一个奇怪的问题。 Sometimes, 1 in 1000 perhaps, we get exceptions from the cache Get method cache.Get(key); 有时,也许每千个中有1个,我们从缓存中获取异常Get方法cache.Get(key); ( public object Get(string key) ). public object Get(string key) )。 The exception is 例外是

Object of type 'System.Collections.Generic.List`1[MyNamespace.PersonName]' cannot be converted to type 'MyNamespace.StatusType'. 类型'System.Collections.Generic.List`1 [MyNamespace.PersonName]'的对象不能转换为'MyNamespace.StatusType'类型的对象。

Why is it trying to do this conversion?? 为什么要进行这种转换? The StatusType Type has nothing to do with the PersonName Type, and its not in its object graph in any way. StatusType类型与PersonName类型无关,并且在其对象图中没有任何关系。

This is internal to the DataCache, and as mentioned above, it will run for days with no issues, then sometimes it just starts throwing exceptions like this around. 这是DataCache的内部功能,并且如上所述,它将运行数天而没有问题,然后有时它只是开始抛出此类异常。 The objects(and object graphs) are all simple enough. 对象(和对象图)都足够简单。 And it does work 99% of the time. 而且确实有99%的时间有效。

Stacktrace: 堆栈跟踪:

at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.RtFieldInfo.InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, Boolean doVisibilityCheck, Boolean doCheckConsistency)
   at System.Runtime.Serialization.FormatterServices.SerializationSetValue(MemberInfo fi, Object target, Object value)
   at System.Runtime.Serialization.FormatterServices.PopulateObjectMembers(Object obj, MemberInfo[] members, Object[] data)
   at Castle.DynamicProxy.Serialization.ProxyObjectReference.DeserializeProxyState()
   at Castle.DynamicProxy.Serialization.ProxyObjectReference..ctor(SerializationInfo info, StreamingContext context)
   at ReadProxyObjectReferenceFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
   at System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
   at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserializeInSharedTypeMode(XmlReaderDelegator xmlReader, Int32 declaredTypeID, Type declaredType, String name, String ns)
   at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, String name, String ns)
   at ReadPersonFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
   at System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
   at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserializeInSharedTypeMode(XmlReaderDelegator xmlReader, Int32 declaredTypeID, Type declaredType, String name, String ns)
   at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, String name, String ns)
   at System.Runtime.Serialization.NetDataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)
   at System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
   at Microsoft.ApplicationServer.Caching.Utility.Deserialize(Byte[][] buffers, Boolean checkTypeToLoad)
   at Microsoft.ApplicationServer.Caching.RoutingClient.SendMsgAndWait(RequestBody reqMsg)
   at Microsoft.ApplicationServer.Caching.DataCache.SendReceive(RequestBody reqMsg)
   at Microsoft.ApplicationServer.Caching.DataCache.InternalGet(String key, DataCacheItemVersion& version, String region)
   at Microsoft.ApplicationServer.Caching.DataCache.Get(String key)
   at MyNamespace.CacheManagement.AppFabricCacheProvider.Get(String key)

Tracked this down eventually. 最终对此进行了追踪。

This issue can occur, if you change the structure of your type, when a cached version of the same type is in the cache, and then try to retrieve a cached instance of the old type, on to your new type. 如果您更改类型的结构,当缓存中存在相同类型的缓存版本,然后尝试将旧类型的缓存实例检索到新类型时,可能会发生此问题。

In an environment with multiple developers working on the same types, sharing the same global cache, you're bound to run into this. 在多个开发人员使用相同类型,共享相同全局缓存的环境中,您一定会遇到这种情况。

Never occurs in production, where the type interfaces would be static. 在生产中绝不会发生类型接口将是静态的。

Example

public class Foo // version 1.0
{
 public string Woof {get;set;}
 public FooBar Meow {get;set;}
}
// compile, run,
// add an instance of Foo to AppFabric Cache, cacheKey = X

// 5 mins later
public class Foo // version 1.1
{
 public int Id {get;set;} // change interface of type
 public string Woof {get;set;}
 public FooBar Meow {get;set;}
}

// compile, run, get an instance of Foo from the cache, cacheKey = X
// exception, with strange information.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM