【发布时间】:2013-01-29 12:25:06
【问题描述】:
我正在使用最新的 protobuf-net lib 和 protobuf-net memcache 提供程序。我需要序列化自定义类型 MyClass 的列表
[ProtoContract]
public class MyClass{
[ProtoMember(1)]
public int a {get; set;}
[ProtoMember(2)]
public int b {get; set;}
}
所以我需要存储/检索:
List<MyClass> myList
当值通过 protobuf 存储然后从缓存中检索时一切顺利。但是,如果值存储在 memcache 中(以正确的 protobuf 格式),即来自另一个线程/应用程序,然后由于类型字段的 NullReferenceExceptions 从缓存反序列化中检索该值失败。
所以当先设置时,序列化值的类型存储在 typeCache 变量中,然后从该字典中检索。但是,如果值存在于内存缓存中但未在当前线程中设置,则 typeCache var 不包含该类型并在反序列化时抛出 NullReference。
有没有办法解决这个问题或一些变通方法?
更深入的调查:
在ProtoTranscoder.cs 中实现的 enyim 的序列化/反序列化过程。它包含具有Dictionary<ArraySegment<byte>, Type> typeCache 的NetTranscoder 类。
因此,当 set 第一个序列化类型(即List<MyClass>)存储在typeCache var 中,一切顺利。如果值存在于内存缓存中,但未在当前应用程序/线程中设置反序列化,则此代码检索它:
type = Type.GetType(enc.GetString(buffer, keyOffset, len));
byte[] standaloneBuffer = new byte[len];
Buffer.BlockCopy(buffer, keyOffset, standaloneBuffer, 0, len);
key = new ArraySegment<byte>(standaloneBuffer, 0, len);
sync.EnterWriteLock();
try
{
// did somebody beat us to it?
Type tmp;
if (typeCache.TryGetValue(key, out tmp)) return tmp;
typeCache.Add(key, type);
return type; <-- Here it returns null, if type not present in typeCache
}
finally
{
sync.ExitWriteLock();
}
重现该错误:
- 列表项
- 在内存缓存中创建和存储一些列表(使用已配置的原型转码器)
- 重启当前应用(或启动另一个线程)
- 尝试从那些“另一个线程”的 memcache 中按键获取值
这是此错误的堆栈跟踪: [ArgumentNullException:值不能为空。 参数名称:类型]
ProtoBuf.Meta.TypeModel.PrepareDeserialize(Object value, Type& type) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:592
ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:577
ProtoBuf.Caching.Enyim.NetTranscoder.Enyim.Caching.Memcached.ITranscoder.Deserialize(CacheItem item) in c:\Users\akureniov\work\protobuf-net-1\protobuf-net.Enyim\protobuf-net.Enyim\ProtoTranscoder.cs:109
Enyim.Caching.MemcachedClient.PerformTryGet(String key, UInt64& cas, Object& value) +179
Enyim.Caching.MemcachedClient.TryGet(String key, Object& value) +42
Enyim.Caching.MemcachedClient.Get(String key) +15
【问题讨论】:
-
请具体说明:您使用的是哪个 dll 版本? “最新的 protobuf-net 库”不包括 enyim 转码器(“扩展”项目尚未针对 v2 进行修订,并且不构建 AFAIK,尽管它在我的列表中查看)。那么:您使用的是旧版本的转码器吗?您是否修补了“扩展”?还是您手动存储类型?
-
您是否正在使用
ProtoTranscoderNuGet 包? -
我正在使用从 svn 源代码编译的 protobuf-net-r622 lib 和 protobuf enyim 模块(它作为单独的项目进入 svn)。 Nuget 包不适用于 couchbase enyim.cache lib 女巫具有不同的公钥。
-
您能准确地指出您正在使用/从源代码编译哪个“protobuf enyim 模块”吗?没有那个很难评论......
-
它位于你的svn中。文件夹名为“protobuf-net.Enyim”。我已将参考 protobuf-net 库更新为 r622 版本,然后对其进行编译。此外,我将很快更新我的第一篇文章,提供更深入的错误痕迹。
标签: .net memcached protobuf-net