最新のprotobuf-netlibをprotobuf-netmemcacheプロバイダーで使用しています。カスタムタイプの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が原因で、キャッシュの逆シリアル化が失敗します。
したがって、setが最初に実行されると、シリアル化された値のタイプがtypeCache変数に格納され、そのディクショナリから取得されます。ただし、値がmemcacheに存在するが、現在のスレッドに設定されていない場合typeCache varにはそのタイプが含まれず、逆シリアル化時にNullReferenceがスローされます。
これまたはいくつかの回避策を修正する方法はありますか?
より詳細な調査:で実装されたenyimのシリアル化/逆シリアル化プロセスProtoTranscoder.cs
。NetTranscoder
を持つクラスが含まれていDictionary<ArraySegment<byte>, Type> typeCache
ます。したがって、setが最初になると、シリアル化されたタイプ(つまり)はvarにList<MyClass>
格納され、すべてうまくいきます。typeCache
値がmemcacheに存在するが、逆シリアル化時に現在のアプリ/スレッドに設定されていない場合、次のコードで取得されます。
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に保存します(構成された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