4

新しいデータが利用可能になるたびに呼び出されるコールバックメソッドがあります。

public delegate void DataCallback(
    byte[] buffer,
    int offset,
    int count);

これを、次のようなインターフェイスを実装するクラスでラップしたいと思います。

public interface IDataSource
{
    IAsyncResult BeginRead(
        byte[] buffer,
        int offset,
        int size,
        TimeSpan timeout,
        AsyncCallback callback,
        object state);

    int EndRead(
        IAsyncResult asyncResult);

    int Read(
        byte[] buffer,
        int offset,
        int size,
        TimeSpan timeout);
}

これは明らかに古典的な生産者/消費者問題です。バイトはコールバックメソッドの呼び出しによって生成され、Begin/EndReadメソッドとReadメソッドによって消費されます。データが利用できない場合(タイムアウトが発生するまで)、Begin/EndReadメソッドとReadメソッドはブロックする必要があります。実装では固定サイズの内部バッファーを使用する必要があるため、バッファーが現在いっぱいになると、コールバックメソッドはブロックする必要があります。

マルチスレッドについて考えると、通常、深刻な頭痛の種になるので、私の質問は次のとおりです。そのようなデータ構造の実装はすでにありますか?

(Readメソッドの実装は非常に簡単なはずですが、Begin / EndRead with Readの実装は避けたいと思います。/ BeginEndInvoke

4

2 に答える 2

1

を介して非同期である必要がありますIAsyncResultか?ここに一般的なブロックキューがあります(つまり、リーダーはデータがあるかデータが閉じられるまでブロックし、ライターはスペースができるまでブロックします)。特に最適化されているわけではありませんが、サイズが大きくない限り、対処する必要があります。ただし、ブロッキングキューとして、(少なくとも1つの)専用のコンシューマスレッドが必要です。byte[]

T val;
while(queue.TryDequeue(out val)) {
    // process val
}
于 2009-05-21T15:00:20.307 に答える
0

「ロックレスキュー」でグーグル検索をするべきだと思います。私はそのようにしてたくさんの有用なヒットを得ました。

于 2009-05-21T14:59:07.033 に答える