Asynchronous BinaryReader and BinaryWriter in .Net?

I would like to read and write bytes and types of structured values, asynchronously, without worrying about decoders and byte offsets: is there anything that would allow me to do this?

+6
source share
1 answer

This is not possible using BinaryReader or BinaryWriter . You can read at the same time as the base BaseStream , but the documentation says the following:

Using the underlying stream while reading or using the BinaryReader can result in data loss and corruption. For example, the same bytes may be read more than once, bytes may be skipped, or reading characters may become unpredictable.

Therefore, the only way is to curtail your own implementation. But the benefits of this are debatable. Microsoft's Marco Greg added the following comment to a blog article Should I disclose asynchronous wrappers for synchronous methods? :

John. The reason BinaryReader / Writer does not have XxxAsync methods is because methods of these types usually only read / write very few bytes from the underlying stream that was previously opened. In practice, data is often cached, and the time required to extract data from the source is usually so short that you should not do this asynchronously.

It is noteworthy that there are some methods for these types, which in some cases can transfer large amounts of data (for example, ReadString). Further down the line, Async versions for these methods may or may not be added, but this is unlikely to happen in the near future.

In general, only Async IO methods should be considered if the amount of data you are reading is significant (at least several hundred or thousand bytes), or if you are accessing the resource for the first time (for example, the first reading from a file may require you to expand the disk, even if you read one byte).

That sounds reasonable. If you need a solution, there are a few workarounds in addition to turning your own BinaryReader / BinaryWriter . You can run it in a separate thread (which may be inefficient), or if you want to change the file format or wired protocol, you can use this template (pseudo-code):

 //read packet length await stream.ReadAsync(buffer); var packetLength=convertToInt(buffer); //read complete packet asynchronously await stream.ReadAsync(buffer,packetLength); //process packet with BinaryReader using(var br=new BinaryReader(new MemoryStream(buffer)) { //... } 

Please note that this pattern is only useful if the full buffer fits easily into memory and that performance may suffer.

+7
source

Source: https://habr.com/ru/post/914124/


All Articles