2

TCP経由でリモートサーバーと通信する単純なWinRTアプリケーションがあります。

これを行うために、新しいStreamSocketオブジェクトを作成し、次のように適切なボタンをクリックした後にリモートサーバーに接続します。

private async void ConnectButtonClick(object sender, RoutedEventArgs e)
{
    StreamSocket socket = new StreamSocket();
    HostName host = new HostName("192.168.1.15");
    await socket.ConnectAsync(host, "12121");
}

問題は、このコードがUIスレッドをブロックしていることです。UIがブロックされているかどうかを確認するために、画面上で継続的に実行されているMonoGame(移動するスプライトのカップル)を使用して、簡単なアニメーションを作成しました。

問題は、[接続]ボタンをクリックした後、アニメーションが1秒間フリーズすることです。したがって、サーバーへの接続はUIスレッドで行われると思います。

ネットワークコード全体を別のスレッドに入れる必要がありますか、それともこの非同期/待機で十分ですか?

次のように、(DataReaderの助けを借りて)着信データを処理するループを実装したいと思います。

private async void ReceiveLoop()
{
    bool running = true;

    while (running)
    {
        try
        {
            uint numStrBytes = await _reader.LoadAsync(BufferSize);

            if (numStrBytes == 0)
            {
                Disconnect();
                return;
            }

            string msg = _reader.ReadString(numStrBytes);

            OnLog(string.Format("Received: {0}", msg));
            OnDataReceived(msg);
        }
        catch (Exception exception)
        {
            OnLog("Receive failed with error: " + exception.Message);

            Disconnect();
            running = false;
        }
    }
}

データの送信は、DataWriterのStoreAsyncを使用して行われます。

では、これらの関数を別々のスレッドに配置する必要がありますか?

4

2 に答える 2

0

バックグラウンドスレッドでそれを実行して、それが役立つかどうかを確認することはできませんか?このようなもの:

Task.Run(
    async () =>
    {
        StreamSocket socket = new StreamSocket();
        HostName host = new HostName("192.168.1.15");
        await socket.ConnectAsync(host, "12121");
    });
于 2012-11-26T06:32:28.130 に答える
0

通常の.netライブラリの非同期呼び出しの場合、一般的なルールは、ConfigureAwait(false)を使用することです。これにより、発生しているような問題を防ぐことができます。したがって、たとえばWinRTのものでは、次のようになります。

待機socket.ConnectAsync(host、 "12121")。AsTask()。ConfigureAwait(false);

これにはいくつかの素晴らしい情報があります:http: //blogs.msdn.com/b/windowsappdev/archive/2012/04/24/diving-deep-with-winrt-and-await.aspx

于 2014-12-04T19:40:03.160 に答える