这是我准备的最小可能情况:
当我打断程序时,我可以看到调用堆栈从task.Wait()开始,以System.Threading.Monitor.Wait()结束。
如果我一步一步地调试这个问题,它就不会卡住。我必须承认,这看起来像是.NET框架的一个bug,但也许我错过了一些显而易见的东西。
- 这段代码连接到imap.gmail.com
- 读取初始服务器问候语(使用Read方法)
- 发送NOOP命令(无操作)
- 读取NOOP命令响应(再次使用Read方法)
当我打断程序时,我可以看到调用堆栈从task.Wait()开始,以System.Threading.Monitor.Wait()结束。
如果我一步一步地调试这个问题,它就不会卡住。我必须承认,这看起来像是.NET框架的一个bug,但也许我错过了一些显而易见的东西。
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
}
}
async
方法的默认行为,使其不在其上下文中恢复。但是,在这种情况下,如果您“选择加入”上下文,仍然会出现相同的死锁问题。没有办法完全避免死锁。 - Stephen Cleary