Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net Protobuf net memcache提供程序反序列化时出现null类型错误_.net_Memcached_Protobuf Net - Fatal编程技术网

.net Protobuf net memcache提供程序反序列化时出现null类型错误

.net Protobuf net memcache提供程序反序列化时出现null类型错误,.net,memcached,protobuf-net,.net,Memcached,Protobuf Net,我正在使用protobuf net memcache提供程序的最新protobuf net lib。我需要序列化自定义类型MyClass的列表 [ProtoContract] public class MyClass{ [ProtoMember(1)] public int a {get; set;} [ProtoMember(2)] public int b {get; set;} } 因此,我需要存储/检索: List<MyClass> myList 要重现该

我正在使用protobuf net memcache提供程序的最新protobuf net lib。我需要序列化自定义类型MyClass的列表

[ProtoContract]
public class MyClass{
  [ProtoMember(1)]
  public int a {get; set;}
  [ProtoMember(2)]
  public int b {get; set;}
}
因此,我需要存储/检索:

List<MyClass> myList
要重现该错误,请执行以下操作:

  • 列表项
  • 在memcache中创建并存储一些列表(使用已配置的prototranscoder)
  • 重新启动当前应用程序(或启动其他线程)
  • 尝试从那些“另一个线程”的memcache中按键获取值
  • 以下是此错误的堆栈跟踪: [ArgumentNullException:值不能为null。 参数名称:类型]

       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
    

    我认为memcache不理解
    ProtoContract
    ,尝试将它们标记为
    DataContract
    ,我们在ProtoTranscoder中的类型修剪中发现了“bug”。cs:NetTranscoder:void WriteType(MemoryStream ms,type type type)。此代码块会导致错误,因为它剪切太多:

    int i = typeName.IndexOf(','); // first split
    if (i >= 0) { i = typeName.IndexOf(',', i + 1); } // second split
    if (i >= 0) { typeName = typeName.Substring(0, i); } // extract type/assembly only
    
    它对简单类型很有效,但在列表、字典等方面失败

    为了避免这种情况,最好使用regexp来剪切非必要信息(如文化、publickkeytoken等)。因此,这里有一个替代品(需要用这个替代上面的行),非常粗鲁,但在大多数情况下都有效:

    typeName = Regex.Replace(typeName, @", Version=\d+.\d+.\d+.\d+", string.Empty);
    typeName = Regex.Replace(typeName, @", Culture=\w+", string.Empty);
    typeName = Regex.Replace(typeName, @", PublicKeyToken=\w+", string.Empty);
    
    此regexp不会剪切自定义类型所需的类型程序集。但对于标准类型,它是
    mscorlib
    ,在大多数情况下,可以通过添加另一行来安全删除:

    typeName = Regex.Replace(typeName, @", mscorlib", string.Empty);
    

    请具体说明:您正在使用哪些dll版本?“最新的protobuf网络库”不包括enyim转码器(“Extensions”项目没有针对v2进行修改,也没有构建AFAIK,尽管它在我的列表中)。那么:您使用的是旧版本的转码器吗?你修补过“扩展”吗?或者您是手动存储类型吗?您是否碰巧使用了
    ProtoTranscoder
    NuGet包?我使用的是protobuf-net-r622 lib和protobuf-enyim模块,它们是从svn的源代码编译而来的(它作为单独的项目进入svn)。Nuget软件包不适用于couchbase enyim。缓存库具有不同的publick密钥。您能准确地告诉我您正在使用/从源代码编译的“protobuf enyim模块”吗?没有它很难评论…它位于您的svn中。名为“protobuf net.Enyim”的文件夹。我已经将参考protobuf网络库更新为版本r622,然后编译了它。另外,我将很快更新我的第一篇文章,更深入地跟踪错误;如果是这样的话,enyim可以做任何它需要的事情。段落应该说“汇编”,而不是“名称空间”-但是看起来不错,谢谢!稍后我会考虑合并它。非常感谢。修复了最后一段。谢谢此外,我在复杂的列表和字典上测试了我的代码,似乎效果很好。删除mscorlib也很好。这个问题解决了吗?我想我在protobuf net v2.0.0.621中看到了这个问题。这也很奇怪——我可以成功地存储一些列表,但不能存储其他列表。它似乎取决于列表的泛型类型。正如我看到的存档打开关闭。网站没有改变。因此,解决这个问题的方法是:从svn获取源代码,替换这些行并编译它。到目前为止,这个修复程序在我们的项目中可以很好地处理我们所有的类型。奇怪的是,我获取了源代码(protobuf net和protobuf net.enyim),但不能用它序列化/反序列化普通的
    [Serializable]
    类(即:没有
    [ProtoContract]
    [DataContract]
    属性)。它与Protobuf-net和Protobuf-net.Enyim的nuget版本一起工作,但不是从我下载的源代码。通过pf-n.enyim单元测试,我发现我的类型未能通过
    TypeModel.cancontractType
    。它适用于nuget版本,而不是我的开源版本。我错过了什么?(protobuf Net的标准.Net 4版本)
    typeName = Regex.Replace(typeName, @", mscorlib", string.Empty);