c# - StreamSocket.InputStreamOptions.ReadAsync 在使用 Wait() 时挂起

标签 c# sockets windows-store-apps

这是最小的可能场景,我能够准备:

  • 此代码连接到 imap.gmail.com
  • 读取初始服务器问候语(使用 Read 方法)
  • 发送 NOOP 命令(NO 操作)
  • 读取 NOOP 命令响应(再次使用 Read 方法)

问题是第二次读取挂起。如果使用“等待 ReadAsync”,它会完美运行。

当我中断程序时,我可以看到调用堆栈从 task.Wait() 开始并在 System.Threading.Monitor.Wait() 结束。

如果我一步步调试它,它不会挂起。我必须承认它看起来像一个 .NET 框架错误,但也许我遗漏了一些明显的东西。

private static async Task<byte[]> ReadAsync(StreamSocket socket)
{
    // all responses are smaller that 1024
    IBuffer buffer = new byte[1024].AsBuffer();
    await socket.InputStream.ReadAsync(
            buffer, buffer.Capacity, InputStreamOptions.Partial);
    return buffer.ToArray();
}

private static byte[] Read(StreamSocket socket)
{
    Task<byte[]> task = ReadAsync(socket);
    task.Wait();
    return task.Result;
}

private async void Button_Click(object sender, RoutedEventArgs e)
{
    Encoding encoding = Encoding.GetEncoding("Windows-1250");

    using (StreamSocket socket = new StreamSocket())
    {
        await socket.ConnectAsync(
            new HostName("imap.gmail.com"), "993", SocketProtectionLevel.Ssl);

        // notice we are using Wait() version here without any problems:
        byte[] serverGreetings = Read(socket);              

        await socket.OutputStream.WriteAsync(
            encoding.GetBytes("A0001 NOOP\r\n").AsBuffer());
        await socket.OutputStream.FlushAsync();

        //byte[] noopResponse = await ReadAsync(socket);    // works
        byte[] noopResponse = Read(socket);                 // hangs
    }
}

最佳答案

我解释了这个死锁的原因in my recent MSDN article以及on my blog .

简短的回答是,您不应该async 代码上调用WaitResult;你应该一直使用await

关于c# - StreamSocket.InputStreamOptions.ReadAsync 在使用 Wait() 时挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16436824/

相关文章:

c# - 在 C# 中使用 `using` 关键字避免多次处置的最佳实践

c# - 在保持双向绑定(bind)的同时将过滤后的 ObservableCollection 绑定(bind)到 ListView?

c# - 从另一个类继承的类是否比不使用继承的类在内存中更大?

c# - 工厂模式 : Determining concrete factory class instantiation?

c# - 参数个数错误(参数化查询)

c# - 套接字 OnData 事件

perl - Perl 中的套接字编程

Java SSL 双向握手错误

c# - 为什么 C# 中需要 "new"关键字

c# - 使用 NUnit 测试 Windows 8 商店应用程序