【问题标题】:How do I wait for an async to complete?如何等待异步完成?
【发布时间】:2014-04-03 14:04:14
【问题描述】:

我目前正在开发一个聊天客户端(Windows 应用商店应用程序 - C#),我目前卡在注册部分。在我将用户名、密码、电子邮件等相关数据发送到服务器以创建新用户之前,我调用函数“CheckSignUp(...)”,它首先检查用户名是否已经存在。它首先发送关键字/F011/,然后发送用户名,然后我应该接收关键字OK或NOK(用户名已经存在)。代码如下:

public async Task<string> CheckSignUp(string username)
    {
        writer.WriteString("/F011/" + "\n");
        writer.WriteString(username + "\n");
        await writer.StoreAsync();

        reader.InputStreamOptions = InputStreamOptions.Partial;
        string result = reader.ReadString(await reader.LoadAsync(3));
        return result;
    }

当我按下“注册”按钮时会调用此函数。问题是我只有在第二次按下“注册”按钮后才会收到错误消息。下面是Button_click事件的相关代码:

private async void bnSignUp_Click(object sender, RoutedEventArgs e)
    {
           ...

            string ValidUser = await App.ChatConnection.CheckSignUp(tbUserName.Text);
            if (ValidUser == "NOK")
            {
                FailText.Children.Add(new InfoTextBox("Error! Username already exists."));
                tbUserName.Text = "";
            }
            ....
    }

在连接到服务器时会创建readerwriter 对象:

socket = new StreamSocket(); 
HostName hostname = new HostName(host); 
await socket.ConnectAsync(hostname, port); 
writer = new DataWriter(socket.OutputStream); 
reader = new DataReader(socket.InputStream);

编辑:我在尝试登录时也遇到了同样的问题(Login() 函数的工作方式与 CheckSignUp 类似):

public async Task<string> Login(string username, string password)
    {
        writer.WriteString("/F050/" + "\n");
        writer.WriteString(GetHash(password) + "\n");
        writer.WriteString("\n");
        writer.WriteString(username + "\n");
        await writer.StoreAsync();

        reader.InputStreamOptions = InputStreamOptions.Partial;
        return reader.ReadString(await reader.LoadAsync(3));
    }

【问题讨论】:

  • 你不要“等待”(或者至少,你不应该)。你“等待”——就像你已经是一样。
  • 那么我该如何解决我的问题呢?
  • 请提供有关readerwriter 对象的更多详细信息。这些是如何以及在哪里创建的?
  • 我在连接到服务器后立即创建了它们:socket = new StreamSocket();主机名主机名 = 新主机名(主机);等待 socket.ConnectAsync(主机名,端口); writer = new DataWriter(socket.OutputStream); reader = new DataReader(socket.InputStream);
  • 欢迎来到异步编程的世界。您需要创建一个将信息发送到服务器的任务,然后在任务的“then”部分处理结果(将请求与响应分开)。您不允许在 GUI 线程上等待/等待。

标签: c# windows windows-8 winrt-xaml async-await


【解决方案1】:

我建议您首先尽量使用 TCP/IP。使用 WebAPI、SignalR 等。

如果您确实需要使用 TCP/IP,那么您需要实现 message framing,正如我在我的博客中所描述的那样。

【讨论】:

    【解决方案2】:

    您可能必须刷新写入器,以便您的数据实际上是通过套接字发送而不是缓冲。

    public async Task<string> CheckSignUp(string username)
    {
        writer.WriteString("/F011/" + "\n");
        writer.WriteString(username + "\n");
        await writer.StoreAsync();
    
        await writer.FlushAsync();
    
        // ..rest of code...
    }
    

    【讨论】:

    • 2 次尝试后工作?尝试在服务器上刷新。
    • 是的,它是一样的。它仅在第二次尝试后才有效。
    猜你喜欢
    • 2020-10-04
    • 2019-05-31
    • 2020-02-22
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 2019-06-16
    相关资源
    最近更新 更多