protobuf-net 子消息未正确读取
Posted
技术标签:
【中文标题】protobuf-net 子消息未正确读取【英文标题】:protobuf-net Sub-message not read correctly 【发布时间】:2013-09-06 05:25:28 【问题描述】:我目前正在测试 protobuf-net(最新版本),但在反序列化时间歇性地出现“子消息未正确读取”异常。到目前为止,还没有明显的模式可以重现此错误,并且数据始终相同。
我用谷歌搜索了这个错误,到目前为止人们只在处理大数据 (>20MB) 时才报告这个错误,我没有这样做。
谁能指出这是否是一个错误(如果是,任何可能的解决方案来修复/规避这个问题?),还是我错过了一些步骤?以下是我正在使用的代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ProtoBuf;
namespace ConsoleApplication1
class Program
static void Main(string[] args)
const string message = "Cycle 0: 1:N2 ms - avg: 2:N2 ms - min: 3:N2 - max: 4:N2";
const int loop = 1000;
var counter = new Stopwatch();
var average = 0d;
var min = double.MaxValue;
var max = double.MinValue;
for (int i = 0;; i++)
var classThree = Create();
counter.Reset();
counter.Start();
Parallel.For(0, loop, j =>
using (var ms = new MemoryStream())
Serializer.Serialize(ms, classThree);
using (var ms2 = new MemoryStream(ms.ToArray()))
var des = Serializer.Deserialize<ClassThree>(ms2);
var aaa = des;
);
counter.Stop();
var elapsed = counter.Elapsed.TotalMilliseconds;
average += elapsed;
min = Math.Min(min, elapsed);
max = Math.Max(max, elapsed);
var currentAverage = average / (i + 1);
Console.Clear();
Console.WriteLine(message, i, elapsed, currentAverage, min, max);
Thread.Sleep(0);
private static ClassThree Create()
var classOne = new ClassSix()
// properties
p_i1 = -123,
p_i2 = 456,
p_l1 = -456,
p_l2 = 123,
p_s = "str",
p_f = 12.34f,
p_d = 56.78d,
p_bl = true,
p_dt = DateTime.Now.AddMonths(-1),
p_m = 90.12m,
p_b1 = 12,
p_b2 = -34,
p_c = 'c',
p_s1 = -21,
p_s2 = 43,
p_ts = new TimeSpan(12, 34, 56),
p_id = Guid.NewGuid(),
p_uri = new Uri("http://www.google.com"),
p_ba = new[] (byte)1, (byte)3, (byte)2 ,
p_t = typeof(ClassTwo),
p_sa = new[] "aaa", "bbb", "ccc" ,
p_ia = new[] 7, 4, 9 ,
p_e1 = EnumOne.Three,
p_e2 = EnumTwo.One | EnumTwo.Two,
p_list = new List<ClassFive>(new[]
new ClassFive()
i = 1,
s = "1"
,
new ClassFive()
i = 2,
s = "2"
),
// fields
f_i1 = -123,
f_i2 = 456,
f_l1 = -456,
f_l2 = 123,
f_s = "str",
f_f = 12.34f,
f_d = 56.78d,
f_bl = true,
f_dt = DateTime.Now.AddMonths(-1),
f_m = 90.12m,
f_b1 = 12,
f_b2 = -34,
f_c = 'c',
f_s1 = -21,
f_s2 = 43,
f_ts = new TimeSpan(12, 34, 56),
f_id = Guid.NewGuid(),
f_uri = new Uri("http://www.google.com"),
f_ba = new[] (byte)1, (byte)3, (byte)2 ,
f_t = typeof(ClassTwo),
f_sa = new[] "aaa", "bbb", "ccc" ,
f_ia = new[] 7, 4, 9 ,
f_e1 = EnumOne.Three,
f_e2 = EnumTwo.One | EnumTwo.Two,
f_list = new List<ClassFive>(new[]
new ClassFive()
i = 1,
s = "1"
,
new ClassFive()
i = 2,
s = "2"
)
;
var classThree = new ClassThree()
ss = "333",
one = classOne,
two = classOne
;
return classThree;
public enum EnumOne
One = 1,
Two = 2,
Three = 3
[Flags]
public enum EnumTwo
One = 1,
Two = 2,
Three = 4
[ProtoContract, ProtoInclude(51, typeof(ClassSix))]
public class ClassOne
// properties
[ProtoMember(1)]
public int p_i1 set; get;
[ProtoMember(2)]
public uint p_i2 set; get;
[ProtoMember(3)]
public long p_l1 set; get;
[ProtoMember(4)]
public ulong p_l2 set; get;
[ProtoMember(5)]
public string p_s set; get;
[ProtoMember(6)]
public float p_f set; get;
[ProtoMember(7)]
public double p_d set; get;
[ProtoMember(8)]
public bool p_bl set; get;
[ProtoMember(9)]
public DateTime p_dt set; get;
[ProtoMember(10)]
public decimal p_m set; get;
[ProtoMember(11)]
public byte p_b1 set; get;
[ProtoMember(12)]
public sbyte p_b2 set; get;
[ProtoMember(13)]
public char p_c set; get;
[ProtoMember(14)]
public short p_s1 set; get;
[ProtoMember(15)]
public ushort p_s2 set; get;
[ProtoMember(16)]
public TimeSpan p_ts set; get;
[ProtoMember(17)]
public Guid p_id set; get;
[ProtoMember(18)]
public Uri p_uri set; get;
[ProtoMember(19)]
public byte[] p_ba set; get;
[ProtoMember(20)]
public Type p_t set; get;
[ProtoMember(21)]
public string[] p_sa set; get;
[ProtoMember(22)]
public int[] p_ia set; get;
[ProtoMember(23)]
public EnumOne p_e1 set; get;
[ProtoMember(24)]
public EnumTwo p_e2 set; get;
[ProtoMember(25)]
public List<ClassFive> p_list set; get;
// fields
[ProtoMember(26)]
public int f_i1 = 0;
[ProtoMember(27)]
public uint f_i2 = 0;
[ProtoMember(28)]
public long f_l1 = 0L;
[ProtoMember(29)]
public ulong f_l2 = 0UL;
[ProtoMember(30)]
public string f_s = string.Empty;
[ProtoMember(31)]
public float f_f = 0f;
[ProtoMember(32)]
public double f_d = 0d;
[ProtoMember(33)]
public bool f_bl = false;
[ProtoMember(34)]
public DateTime f_dt = DateTime.MinValue;
[ProtoMember(35)]
public decimal f_m = 0m;
[ProtoMember(36)]
public byte f_b1 = 0;
[ProtoMember(37)]
public sbyte f_b2 = 0;
[ProtoMember(38)]
public char f_c = (char)0;
[ProtoMember(39)]
public short f_s1 = 0;
[ProtoMember(40)]
public ushort f_s2 = 0;
[ProtoMember(41)]
public TimeSpan f_ts = TimeSpan.Zero;
[ProtoMember(42)]
public Guid f_id = Guid.Empty;
[ProtoMember(43)]
public Uri f_uri = null;
[ProtoMember(44)]
public byte[] f_ba = null;
[ProtoMember(45)]
public Type f_t = null;
[ProtoMember(46)]
public string[] f_sa = null;
[ProtoMember(47)]
public int[] f_ia = null;
[ProtoMember(48)]
public EnumOne f_e1 = 0;
[ProtoMember(49)]
public EnumTwo f_e2 = 0;
[ProtoMember(50)]
public List<ClassFive> f_list = null;
[ProtoContract]
public class ClassSix : ClassOne
[ProtoContract]
public class ClassTwo
[ProtoContract]
public interface IClass
[ProtoMember(1)]
string ss
set;
get;
[ProtoMember(2)]
ClassOne one
set;
get;
[ProtoContract]
public class ClassThree : IClass
[ProtoMember(1)]
public string ss set; get;
[ProtoMember(2)]
public ClassOne one set; get;
[ProtoMember(3)]
public ClassSix two set; get;
[ProtoContract]
public class ClassFour
[ProtoMember(1)]
public string ss set; get;
[ProtoMember(2)]
public ClassOne one set; get;
[ProtoContract]
public class ClassFive
[ProtoMember(1)]
public int i set; get;
[ProtoMember(2)]
public string s set; get;
【问题讨论】:
FWIW 我在 .Net 4.0 / PBuf v 2.0.0.640 上运行了大约 5000 次代码循环,没有出现问题:-( 是的,它是随机发生的。一旦我运行它超过2小时没有任何问题。然而在另一个例子中,我在几千个周期后得到了异常。 我会调查 - 现在不能做太多事情 (mobile.twitter.com/marcgravell/status/375875031538348032/photo/…) 顺便说一句 - 最新版本包括一些对象池 - 我首先要看的是那里的线程竞赛...... 根据@MarcGravell 的评论,我尝试使用 Parallel.For 而不是 for 循环,并且错误发生的频率更高。 【参考方案1】:更新到 rev. 669,到目前为止还没有再次遇到错误。所以我现在报告此问题已修复。
【讨论】:
我认为 r668 解决了这个问题,但是是的:发现了一个错误 我看到的最新版本是r668。请问在哪里可以找到r669? 我只看到 r668 有没有 r669?以上是关于protobuf-net 子消息未正确读取的主要内容,如果未能解决你的问题,请参考以下文章
使用 ProtoBuf-net 反序列化派生类型(字典)未正确设置对象字段