まとめ
私はWinRTでWAVファイル形式リーダーを開発しています。このため、int
、uint
、float
などの基本的な型で構成される構造体をランダムに読み取る必要がありますオン。
デスクトップ開発に戻ると、依存するのは BinaryReader ですが、WinRTでは非同期に動作する DataReader に置き換えられました。
問題
私はこの新しいクラスの使い方を理解できません。これは、中間バッファーを LoadAsync() を使用して埋める必要があります。事前に ReadInt32() などの読み取りメソッドを呼び出します。
対照的に、古い BinaryReader では、ソースからプリミティブを読み取る前に中間バッファーを埋める必要があるという概念はありませんでした。
私がウェブで見たすべての例は、メモリ内のソースストリームを完全に読み取るという意味では「素朴」ですが、私の場合、WAVファイルは数百メガバイト、場合によってはギガバイトの範囲にあります。
次のヘルパーメソッドをスケッチして、必要なものだけで中間バッファーを事前に満たし、ストリームから何かを読み取る前に毎回LoadAsync
を体系的に呼び出す必要がないようにします。
internal static class DataReaderExtensions
{
public static async Task<string> ReadStringAsync(this DataReader reader, uint length)
{
await LoadAsync(reader, length);
return reader.ReadString(length);
}
private static async Task LoadAsync(DataReader reader, uint length)
{
var u = await reader.LoadAsync(length);
if (u < length) throw new InvalidOperationException();
}
}
しかし、それがDataReader
を使用する場合の方法かどうかは、完全にはわかりません。
質問
私の場合、中間バッファをどのように事前に満たすのですか?
DataReader
をヘルパークラスでラップする)[〜#〜]編集[〜#〜]
BinaryReaderのソースコード を見ると、舞台裏にmagicのようなものはないようです。つまり、バイトはオンデマンドでフェッチされます。したがって、私の場合、プリミティブを非同期に読み取るのは少しばかげているように思えますが、それが最も簡単で安全な方法だと思います。 DataReader
のラップ、読み取り位置の追跡、中間バッファーの処理とは対照的に、パブリックWinRT型はシールする必要があるため、そこから派生することができません...結果にとって価値があるかどうかは不明です。
残念ながらWINMDアセンブリのソースは使用できません。これらの新しい型を これらの拡張メソッド を使用して古い型として使用できるため、Microsoftでどのように動作するかを見るのはかなり興味深いでしょう。
上記のように必要な量だけをロードする必要がありますか?
次のコードで処理できると期待できるすべてのものをバッファにロードする必要があります。 DataReader のドキュメントの例では、ストリーム全体をすぐに処理するため、ストリーム全体をバッファーに読み取ります。
バッファの理由は、IOが遅い(通常)であるためです。したがって、指定したデータの量は非同期でロードされますIO先にメモリバッファに。その後、読み取りごとにIOを待たずにそれを読み取ることができます。これはパフォーマンスにとって良いことです。IOはバッチ処理されるため、多くのデバイスのパフォーマンスが向上します(例:機械式ハードドライブ)IO)が終了するまで、コードの実行は(非同期/待機により)一時停止されるため、CPUサイクルを占有しません。
または、一定のサイズ(例:65536バイト)をロードし、読み取り位置を追跡してから、より大きなリクエストでさらにプリフェッチする必要がありますか? (基本的にはDataReaderをヘルパークラスでラップする)
データのサイズが大きすぎて一度にメモリにロードできない場合があります。 .NET自体は、オブジェクトごとに2GBのメモリ制限を設定します( well、sortof )。したがって、読み取るデータが2GBに近い場合は、ストリームの読み取り位置を追跡し、ファイルの一部のみをバッファーに読み取る必要があります。次に、バッファーの終わりに達したら、次の読み取り位置からバッファーを再び埋めて、処理を続行します。ファイル全体を処理するまで、必要に応じて繰り返します。