Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets ConnectAsync阻塞UI线程_Sockets_Tcp_Windows Runtime_Block_Async Await - Fatal编程技术网

Sockets ConnectAsync阻塞UI线程

Sockets ConnectAsync阻塞UI线程,sockets,tcp,windows-runtime,block,async-await,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"

我有一个简单的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线程中进行的

我应该把整个网络代码放在一个单独的线程中,还是这个异步/等待就足够了

我想实现一个循环,它将处理传入的数据(在ODDataReader的帮助下),如下所示:

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;
        }
    }
}
Task.Run(
    async () =>
    {
        StreamSocket socket = new StreamSocket();
        HostName host = new HostName("192.168.1.15");
        await socket.ConnectAsync(host, "12121");
    });
将使用DataWriter中的StoreAsync发送数据


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

难道你不能在后台线程中尝试这样做,看看是否有帮助吗?大概是这样的:

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;
        }
    }
}
Task.Run(
    async () =>
    {
        StreamSocket socket = new StreamSocket();
        HostName host = new HostName("192.168.1.15");
        await socket.ConnectAsync(host, "12121");
    });

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

await socket.ConnectAsync(主机,“12121”).AsTask().ConfigureAwait(false)

这有一些很好的信息:

谢谢,使用这种方式不会阻塞UI线程(连接时不会冻结)。问题是,在发送/接收来自服务器的消息时,我仍然看到短暂冻结,但我认为这与我的另一个问题有关,我在这里问过:我认为这不是一个好的解决方案,因为它没有揭示根本问题。它掩盖了一切。