2012-04-25 12 views
6

Chciałbym czytać i pisać bajty i typy wartości strukturalnych, asynchronicznie, bez martwienia się o dekodery i przesuwanie bajtów: czy jest coś, co pozwoli mi to zrobić?Asynchroniczny BinaryReader i BinaryWriter w .Net?

+0

Co powiesz na "Stream.BeginRead" itp? –

+0

To jest w strumieniu, a nie BinaryReader i BinaryWriter. – Henrik

+0

chcesz odczytać/zapisać bajty; nie potrzebujesz do tego '' BinaryReader'/'BinaryWriter' - są one faktycznie nieaktywne w tym celu. –

Odpowiedz

7

Nie jest to możliwe z BinaryReader lub BinaryWriter. Można czytać równolegle z podstawowej BaseStream, ale documentation stwierdza co następuje:

Korzystanie z podstawowej strumienia podczas czytania lub podczas korzystania z BinaryReader może spowodować utratę danych i korupcji. Na przykład te same bajty mogą być czytane więcej niż raz, bajty mogą być pomijane lub czytanie znaków może stać się nieprzewidywalne.

Dlatego jedynym sposobem jest wdrożenie własnej implementacji. Ale korzyść z tego jest dyskusyjna. Marco Greg od Microsoft dodał do komentarza blogu Should I expose asynchronous wrappers for synchronous methods?:

Jon: Dlatego, że BinaryReader/Writer nie mają metody XxxAsync jest, że metody na tych typów zazwyczaj czytać/pisać tylko bardzo mało bajtów z podstawowy strumień, który został wcześniej otwarty. W praktyce dane są często buforowane, a czas wymagany do pobrania danych z podstawowego źródła jest na ogół tak mały, że nie warto wykonywać go asynchronicznie.

Należy zauważyć, że istnieje kilka metod na tych typach, które w pewnych okolicznościach mogą przenosić większe ilości danych (np. ReadString). W dalszej części, wersje Async dla tych metod mogą być dodawane lub nie, ale jest mało prawdopodobne, że dojdzie do nich w najbliższej przyszłości.

Ogólnie rzecz biorąc, należy brać pod uwagę tylko metody Async IO, jeśli ilość odczytanych danych jest znacząca (co najmniej kilkaset lub tysiące bajtów) lub jeśli użytkownik uzyskuje dostęp do zasobu po raz pierwszy (np. odczyt z pliku może wymagać rozpędzenia dysku, nawet jeśli czytasz jeden bajt).

To brzmi rozsądnie. Jeśli potrzebujesz rozwiązania, istnieje kilka obejść, oprócz toczenia własnych BinaryReader/BinaryWriter. Można go uruchomić w osobnym wątku (który może być nieskuteczne) lub jeśli jesteś gotów do zmiany formatu pliku lub protokół z drutu można użyć tego wzoru (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)) 
{ 
    //... 
} 

Należy pamiętać, że Wzór jest użyteczny tylko wtedy, gdy cały bufor łatwo mieści się w pamięci i wydajność może ucierpieć.