2

私はストリームの読み取りと書き込みに Async パターンを使用することに比較的慣れていないので、この質問に対する答えがあまりに明白で、どこにも明示的に書かれていないのではないかと思いました。

を呼び出すときNetworkStream.BeginReadに、MSDN によると「BeginRead が完了したときに」実行されるコールバック パラメータを渡します。また、「コールバック メソッドは EndRead メソッドを呼び出す必要があります」とも書かれています。

次に、のドキュメントによるとNetworkStream.EndRead、「メソッドは、BeginRead メソッドで開始された非同期読み取り操作を完了します。」また、このメソッドは「データが利用可能になるまでブロックする」ことにも言及しています。

EndRead メソッドは、受信したバイト数を判断するのにも役立つことを知っています。

私の質問は:

EndRead メソッドが BeginRead コールバック内で呼び出された場合、実際にブロックされることはありますか? コールバックが呼び出されたとき、読み取り操作はすでに完了していませんか?

サンプルコード

    byte[] streamBuffer = new byte[1024];

    public void SomeFunction()
    {
        TcpClient client = new TcpClient();
        client.Connect(IPAddress.Parse("127.0.0.1"), 32000);

        NetworkStream stream = client.GetStream();

        stream.BeginRead(streamBuffer,0,streamBuffer.Length,ReadCallback,stream);
    }

    public void ReadCallback(IAsyncResult ar)
    {
        NetworkStream stream = ar.AsyncState as NetworkStream;

        // Will this call ever actually "block" or will it
        // return immediately? Isn't the read operation
        // already complete?
        int bytesRead = stream.EndRead(ar);

        // Other stuff here
    }
4

3 に答える 3

1

EndRead は、次の 2 つの状況で使用できます。

  • コールバック関数で EndRead を使用できます。この時点で、何もブロックされません。
  • コールバック関数なしで EndRead を使用することもできます。

    myStream.BeginRead(...);
    // 同時に多くの作業を行います。
    // 作業が完了したら、ストリームが作業を終了するのを待ちます。
    myStream.EndRead(...);

エラーが発生したことを報告するには、常に EndRead を呼び出す必要があります。エラーが発生した場合、EndReadは例外をスローします。

于 2013-04-29T14:18:02.560 に答える