ConnectAsync阻止UI线程

时间:2012-11-25 23:28:44

标签: sockets tcp windows-runtime block async-await

我有简单的WinRT应用程序,它将通过TCP与远程服务器通信。

为了做到这一点,我正在创建新的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线程。我创建了简单的动画,使用在屏幕上连续运行的MonoGame(几个移动的精灵),以检查UI是否被阻止。

问题是,单击“连接”按钮后,动画会冻结一秒钟,所以我认为,在UI线程中连接到服务器。

我应该把我的整个网络代码放到一个单独的线程中,还是这个async / await足够吗?

我想实现一个循环,它将处理传入的数据(使用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完成发送数据。

那么我应该将这些函数放入单独的线程中吗?

2 个答案:

答案 0 :(得分:0)

难道你不能在后台线程上尝试这样做,看看是否有帮助?像这样:

Task.Run(
    async () =>
    {
        StreamSocket socket = new StreamSocket();
        HostName host = new HostName("192.168.1.15");
        await socket.ConnectAsync(host, "12121");
    });

答案 1 :(得分:0)

对于普通.net库中的任何异步调用,一般规则是使用ConfigureAwait(false),这有助于防止您看到的问题。例如,在WinRT中,它将是:

await socket.ConnectAsync(host," 12121")。AsTask()。ConfigureAwait(false);

这有一些很好的信息: http://blogs.msdn.com/b/windowsappdev/archive/2012/04/24/diving-deep-with-winrt-and-await.aspx