【问题标题】:ConnectAsync blocking UI ThreadConnectAsync 阻塞 UI 线程
【发布时间】:2012-11-25 23:28:43
【问题描述】:

我有一个简单的 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 发送数据。

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

【问题讨论】:

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


    【解决方案1】:

    您不能尝试在后台线程上执行此操作以查看是否有帮助吗?像这样的:

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

    【讨论】:

    • 谢谢,使用这种方式不会阻塞 UI 线程(连接时不会冻结)。问题是我在从服务器发送/接收消息时仍然看到短暂的冻结,但我认为它与我在这里提出的另一个问题有关:stackoverflow.com/questions/13561731/winrt-blocking-task
    • 我认为这不是一个好的解决方案,因为它没有发现根本问题。它掩盖了它。
    【解决方案2】:

    对于普通 .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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 1970-01-01
      相关资源
      最近更新 更多