11

デコーダーやバイトシフトについて心配することなく、バイトと構造化された値の型を非同期で読み書きしたいのですが、それを可能にするものはありますか?

4

3 に答える 3

9

BinaryReaderまたはでは不可能BinaryWriterです。基になる から同時に読み取ることができますBaseStreamが、ドキュメントには次のように記載されています。

読み取り中または BinaryReader の使用中に基になるストリームを使用すると、データの損失や破損が発生する可能性があります。たとえば、同じバイトが複数回読み取られたり、バイトがスキップされたり、文字の読み取りが予測不能になったりする可能性があります。

したがって、唯一の方法は、独自の実装を展開することです。しかし、それを行う利点については議論の余地があります。Microsoft の Marco Greg が次のコメントをブログ記事に追加しました: 同期メソッドの非同期ラッパーを公開する必要がありますか? :

Jon: BinaryReader/Writer に XxxAsync メソッドがない理由は、これらの型のメソッドは通常、以前に開かれた基になるストリームからごくわずかなバイトしか読み書きしないためです。実際には、データは頻繁にキャッシュされ、基になるソースからデータを取得するのに必要な時間は通常非常に短いため、非同期で行う価値はありません。

特に、これらの型には、状況によっては大量のデータを転送する可能性のあるメソッドがいくつかあります (例: ReadString)。今後は、これらのメソッドの Async バージョンが追加される場合と追加されない場合がありますが、近い将来に発生する可能性は低いです。

一般に、読み取るデータの量が多い場合 (少なくとも数百または数千バイト)、またはリソースに初めてアクセスする場合 (ファイルからの最初の読み取りなど) にのみ、非同期 IO メソッドを検討する必要があります。 1 バイトを読み取る場合でも、ディスクをスピンアップする必要がある場合があります)。

これは合理的に聞こえます。解決策が必要な場合は、独自の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))
{
  //...
}

このパターンは、バッファ全体が簡単にメモリに収まる場合にのみ有用であり、パフォーマンスが低下する可能性があることに注意してください。

于 2013-04-02T12:05:36.880 に答える
1

これらのクラスの非同期バージョンを作成しました: https://github.com/ronnieoverby/AsyncBinaryReaderWriter

使用例:

async Task Main()
{
    using var ms = new MemoryStream();
    using var writer = new AsyncBinaryWriter(ms);
    await writer.WriteAsync("today is: ");
    await writer.WriteAsync(DateTime.Today.Ticks);
    await writer.FlushAsync();

    ms.Position = 0;

    using var reader = new AsyncBinaryReader(ms);
    var preamble = await reader.ReadStringAsync();
    var payload = new DateTime(await reader.ReadInt64Async());

    Console.WriteLine(preamble + payload);
}

BCL バイナリ リーダー/ライター クラスに存在する同じ読み取り/書き込みメソッドがすべて存在します。

于 2017-09-08T03:00:01.580 に答える