由于未知原因,对可等待异步函数的第一次调用是同步的

本文关键字:函数 等待 异步 第一次 同步 调用 于未知 未知 | 更新日期: 2023-09-27 18:12:15

我目前正在使用WPF 4.5和Visual Studio 11 Developer Preview。我使用async-await的东西在应用程序事件处理程序异步执行http请求。问题是第一次调用wawait -able方法会挂起应用程序线程,直到它完成。所有后续调用都可以,也就是说,当它们执行时,应用程序仍然可用。

下面是我的代码(只有有意义的部分):

XAML

<toolkit:AutoCompleteBox FilterMode="None" 
                         Margin="5,0,5,0" 
                         x:Name="textArrival" 
                         Populating="textArrival_Populating"
                         SelectionChanged="textArrival_SelectionChanged"/>
c#后台代码:

private async void textArrival_Populating(object sender, PopulatingEventArgs e)
        {
            e.Cancel = true;
            textDeparture.ItemsSource = await model.ProcessStationRequest(textArrival.Text); 
            textArrival.PopulateComplete();
        }

来自上一段代码的可等待调用源:

public async Task<object[]> ProcessStationRequest(string request)
        {
        // omitted: preparing the request into MemoryStream outputStream
        // ...    
        HttpResponseMessage response = await httpClient.PostAsync(hostName, outputStream);
        // omitted: parsing the XML response to an object responseContainer 
        // and returning its member Items, which are of type object[] 
        //...
        return responseContainer.Items;
        }

当我调试和设置断点后行…等待httpClient.PostAsync……,我看到它真的是这个调用挂起了我的应用程序,当请求被处理时(大约2秒)。但如果我把断点放在可等待调用的行上,它会在自动完成文本框填充开始后立即发生。没有什么在两者之间,至少在我的代码中,这就是为什么我假设它是等待调用httpClient使我的应用程序挂起。

你能指出导致这种奇怪行为的代码中的一些问题吗?

由于未知原因,对可等待异步函数的第一次调用是同步的

您可能遇到了HttpWebRequest的已知问题。这个对象上的"异步"方法实际上并不是(完全)异步的。(

现在,我建议将PostAsync包装在Task.Run中。

我已经把这个问题提交给了WCF (HttpClient)团队,异步团队也在研究它。到目前为止还没有真正的回应。