ConfigureAwait(false)仍然死锁

本文关键字:死锁 false ConfigureAwait | 更新日期: 2023-09-27 18:29:31

我已经阅读了一些关于async/await的内容,并试图在执行任务时通过在UI线程上调用WebClient.DownloadStringTaskAsync,然后在UI线程中调用task.Result,在windows窗体中重现死锁场景。这导致了僵局。

然后,我试图通过对返回的任务调用ConfigureAwait(false)来解决这个问题,但令我惊讶的是,这仍然导致了死锁。我的理解是,它应该在不同的线程上执行方法的延续,因此不应该出现死锁。我错过了什么?

我知道如何解决这个问题,但认为ConfigureAwait(false)也会解决这个问题。

这是代码,我使用的是NET4.5

    private async void button1_Click(object sender, EventArgs e)
    {
        // Deadlocks!
        Task<string> task = DownloadAsync();
        textBox1.Text = task.Result;
        // Works
        //textBox1.Text = await DownloadAsync();
    }
    private static async Task<string> DownloadAsync()
    {
        var client = new WebClient();
        string result = await client.DownloadStringTaskAsync("http://www.rpmglobal.com").ConfigureAwait(false);          
        return result;
    }

ConfigureAwait(false)仍然死锁

WebClient仍然会导致此死锁,因为DownloadStringTaskAsync只是EAP方法的包装器,而EAP方法总是在原始上下文中引发它们的事件。没有办法关闭这个。

尝试使用HttpClient(或类似Task.Delay的简单方法)来查看差异。