我有一个简单的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线程中进行的。
我应该将整个网络代码放入一个单独的线程中,还是这个异步/等待就足够了?
我想实现一个循环,它将处理传入的数据(在 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;
}
}
}
发送数据将使用DataWriter的StoreAsync完成。
那么我应该把这些函数放到单独的线程中吗?
您不能尝试在后台线程上执行此操作以查看是否有帮助吗?像这样:
Task.Run(
async () =>
{
StreamSocket socket = new StreamSocket();
HostName host = new HostName("192.168.1.15");
await socket.ConnectAsync(host, "12121");
});
对于普通 .net 库中的任何异步调用,一般规则是使用 ConfigureAwait(false),这有助于防止出现类似问题。因此,例如在WinRT中,它将是:
等待套接字。ConnectAsync(host, "12121").AsTask()。ConfigureAwait(false);
这有一些很好的信息:http://blogs.msdn.com/b/windowsappdev/archive/2012/04/24/diving-deep-with-winrt-and-await.aspx