2012-04-25 21 views
6

我想讀取和寫入字節和結構化的值類型,異步,而不必擔心解碼器和字節移位:是否有什麼東西可以讓我做到這一點?.NET中的異步BinaryReader和BinaryWriter?

+0

'Stream.BeginRead'等怎麼樣? – 2012-04-25 12:14:00

+0

這是在流,而不是BinaryReader和BinaryWriter。 – Henrik 2012-04-25 12:23:41

+0

你想讀取/寫入字節;你不需要'BinaryReader' /'BinaryWriter' - 他們確實對此沒有幫助。 – 2012-04-25 12:30:05

回答

7

這不可能與BinaryReaderBinaryWriter。你可以從底層BaseStream同時讀取,但documentation規定如下:

使用底層流讀取或同時使用BinaryReader在可能導致數據丟失和損壞。例如,相同的字節可能會被讀取多次,字節可能會被跳過,或者字符讀取可能變得不可預測。

因此唯一的方法就是推出自己的實現。但是做這件事的好處是值得商榷的。從微軟馬可格雷格添加到博客文章Should I expose asynchronous wrappers for synchronous methods?以下注釋:

喬恩:之所以說BinaryReader在/作家沒有XxxAsync方法是,在這些類型的方法通常讀/寫距離只有極少數的字節一個先前已打開的基礎流。在實踐中,數據經常被緩存,從底層源獲取數據所需的時間通常非常短,以至於不值得以異步方式進行。

值得注意的是,在這些類型中有一些方法在某些情況下可能傳輸大量數據(例如ReadString)。更進一步說,這些方法的異步版本可能會也可能不會被添加,但它不太可能在不久的將來發生。

通常,如果您正在讀取的數據量很大(至少有幾百或幾千字節),或者您是第一次訪問資源(例如第一次),則應該只考慮異步IO方法即使讀取一個字節,從文件中讀取也可能需要旋轉磁盤)。

這聽起來很合理。如果您確實需要解決方案,除了滾動您自己的BinaryReader/BinaryWriter之外,還有幾種解決方法。您可以在一個單獨的線程(這可能是低效的)運行它,或者如果你願意改變,你可以使用這個模式的文件格式或有線協議(僞代碼):

//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)) 
{ 
    //... 
} 

請注意,這模式僅在完整緩衝區容易適應內存並且性能可能受損時纔有用。