我目前正在测试protobuf net(最新版本),但在反序列化时,间歇性地出现“子消息未正确读取”异常。到目前为止还没有明显的模式来重现这个错误,而且数据总是一样的。
我在谷歌上搜索了这个错误,到目前为止,人们只在处理大数据(>20MB)时才会报告这个错误,我没有这样做。
有谁能指出这是否是一个bug(如果是的话,有没有可能的解决方案来解决/规避这个问题?),还是我漏了几步?下面是我正在使用的代码:
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; }
}
}
最佳答案
更新至版本669到目前为止还没有遇到这个错误。所以我现在把这个报告成固定的。