异步protobuf序列化
protobuf-net实现的一个限制是它同步调用底层流。 通过不提供异步API,例如BeginSerialize / EndSerialize或TPL等价物,我们被迫绑定一个等待同步流I / O的线程。
有没有计划在protobuf-net中提供异步方法,或者有任何创造性的方法来解决这个问题?
不,这目前不受支持,并且会做很多工作。
我的建议是:使用异步API自己缓冲数据,然后在获得数据时,使用类似MemoryStream
来反序列化…
在我的辩护中,我不知道在这里提供异步API的任何其他序列化程序。 特别是,在谈论慢/异步流时,这通常意味着“网络”:你通常会在那里考虑“框架”的问题; protobuf-net不会知道您的框架要求……
您可以等待将在线程池中运行同步代码的Task.Run
。 它不是最有效的解决方案,但它比阻止更好。 您甚至可以将自己的CancellationToken
提交给Task.Run
:
await Task.Run(() => Serializer.SerializeWithLengthPrefix( stream, data, PrefixStyle.Base128), cancellationToken);
或者,您可以使用从我的JuiceStream库中提取的一个非常简单的帮助方法,该方法已作为异步function请求的一部分提交给protobuf-net :
await ProtobufEx.SerializeWithLengthPrefixAsync( stream, data, PrefixStyle.Base128, cancellationToken); await ProtobufEx.DeserializeWithLengthPrefixAsync( stream, PrefixStyle.Base128, cancellationToken);
我在网络上使用protobuff。 虽然以下解决方案并不能保证它不会阻塞,但它确实让生活变得更好:
byte[] emptyByteArray = new Byte[0]; await stream.ReadAsync(emptyByteArray, 0, 0); TaskData d = Serializer.DeserializeWithLengthPrefix(stream, PrefixStyle.Base128);
因为我们在开始反序列化之前确保流上有实际数据,所以只有当流包含部分消息时才会阻塞。
编辑:我们可以使用类似的技巧进行序列化:
MemoryStream mstm = new MemoryStream(); Serializer.SerializeWithLengthPrefix(mstm, data, PrefixStyle.Base128); await stream.WriteAsync(mstm.GetBuffer(), 0, (int)mstm.Position);
作为奖励,这个确保永远不会阻止。
上述就是C#学习教程:异步protobuf序列化分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/992628.html