1

TcpClientCompactFramework2.0アプリケーションの1つでを使用しています。TCPサーバーから情報を受け取りたい。

Compact Frameworkは「大規模な」フレームワークのタイムアウトメカニズムをサポートしていないため、独自のタイムアウト機能を実装しようとしています。基本的に、私は次のことをしたいと思います。

IAsyncResult result = networkStream.BeginRead(buffer, 0, size, ..., networkStream);
if (!result.AsyncWaitHandle.WaitOne(5000, false))
  // Handle timeout


private void ReceiveFinished(IAsyncResult ar)
{
  NetworkStream stream = (NetworkStream)ar.AsyncState;
  int numBytes = stream.EndRead(ar);

  // SIGNAL IASYNCRESULT.ASYNCWAITHANDLE HERE ... HOW??
}

を呼び出したいSetのですがIAsyncResult.AsyncWaitHandle、そのようなメソッドがなく、どの実装にキャストするのかわかりません。

待機ハンドルを設定するにはどうすればよいですか?それとも、を呼び出すことで自動的に設定されEndReadますか?ドキュメントは、私が自分自身を呼び出さなければならないことを示唆していますSet...

助けてくれてありがとう!

UPDATE
呼び出し時に待機ハンドルが自動的に設定されているようEndReadですが、ドキュメントにはありません。誰かがこれを確認できますか?

UPDATE2サンプルコードを
書きました。client.BeginReadもちろん、BeginReadと呼ばれていNetworkStreamます...

4

1 に答える 1

2

TCPとの非同期IOについて誤解していると思います。

非同期IOを開始するには、stream.BeginRead()を呼び出します。
コールバックでは、ストリームでEndReadを呼び出します。

コードが示すように、TcpClientでBeginReadを呼び出さないでください。アプリがWaitHandleにシグナルを送ることはありません。IOレイヤーは、ウェイトハンドルが通知されたとき、つまり非同期読み取りが発生したときにコールバックを呼び出します。

コールバックでは、より多くのデータを受信する可能性がある場合は、通常、ストリームでBeginReadを再度呼び出します。

この回答で明確な例を見ることができます。

BeginRead / EndReadダンスを開始する前に、TcpClientで非同期接続を実行することをお勧めします。その後、BeginConnectを使用します。しかし、それは一度だけ行われます。または、同期接続が必要な場合もあります。その場合は、TcpClient.Connect()を呼び出すだけです。

サンプルコード:

    private class AsyncState
    {
        public NetworkStream ns;
        public ManualResetEvent e;
        public byte[] b;
    }

    public void Run()
    {
        NetworkStream networkStream = ...;
        byte[] buffer = new byte[1024];

        var completedEvent = new ManualResetEvent(false);

        networkStream.BeginRead(buffer, 0, buffer.Length,
                                AsyncRead,
                                new AsyncState
                                {
                                    b = buffer,
                                    ns = networkStream,
                                    e = completedEvent
                                });

        // do other stuff here. ...

        // finally, wait for the reading to complete
        completedEvent.WaitOne();
    }


    private void AsyncRead(IAsyncResult ar)
    {
        AsyncState state = ar as AsyncState;
        int n = state.ns.EndRead(ar);
        if (n == 0)
        {
            // signal completion
            state.e.Set();
            return;
        }

        // state.buffer now contains the bytes read
        // do something with it here...
        // for example, dump it into a filesystem file. 

        // read again
        state.ns.BeginRead(state.b, 0, state.b.Length, AsyncRead, state);
    }
于 2010-03-18T02:48:05.607 に答える