2012-11-25 162 views
2

我有一个简单的WinRT应用程序,它将通过TCP与远程服务器进行通信。ConnectAsync阻塞UI线程

为了做到这一点,我创建新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线程中进行的。

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

我想实现一个循环,将处理传入的数据(与帮助OD 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; 
     } 
    } 
} 

发送数据将使用StoreAsync从DataWriter来完成。

所以我应该把这些功能放到不同的线程中吗?

回答

0

难道你不能只是尝试在后台线程上做到这一点,看看是否有帮助?事情是这样的:

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

谢谢,使用这种方式不会阻塞UI线程(没有冻结,同时连接)。 问题是,当我从服务器发送/接收消息时,我仍然看到很短的冻结,但我认为它与我在这里问的其他问题有关:http://stackoverflow.com/questions/13561731/ winrt-blocking-task – Axadiw

+0

我认为这不是一个好的解决方案,因为它没有发现基本问题。它涵盖了它。 – usr