异步等待模式帮助。我做得对吗?

时间:2012-08-21 03:37:18

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

我有一个“api”,例如存储库模式,我写了从Web返回xml,然后将其水合成类。

似乎挂起了GetXmlAsync(url)方法的结果。

public async Task<string> GetXmlAsync(string url)
{
    string xml = string.Empty;

    HttpMessageHandler handler = new HttpClientHandler();
    HttpClient httpClient = new HttpClient(handler);
    Uri uri = new Uri(url, UriKind.Absolute);
    HttpResponseMessage response = await httpClient.GetAsync(uri);

    xml = await response.Content.ReadAsStringAsync();

    return xml;
}

但是当我在单元测试中使用相同的代码时,它可以工作。

在应用程序中,我称之为:

public async Task<IEnumerable<Post>> GetRecentAsync(int page)
{
    string url = this.urls.GetRecent(page);
    string xml = string.Empty;

    var xmlTask = this.loader.GetXmlAsync(url);

    xml = xmlTask.Result; // Hangs right here.

    var results = this.modelLoader.XmlToPost(xml);

    if (results.Count() < 1)
    {
        this.LastError = XmlLoadError;
    }

    return results.AsEnumerable();
}

[TestMethod]
public async Task Integration_HttpLoader_GetXmlAsync_GetRecent_Xml_ShouldNotBeNullOrEmpty()
{
    int page = 1;
    string xml = string.Empty;
    IUrl url = this.GetUrlHelper();
    ILoader loader = this.GetIntegrationLoader(false);

    xml = await loader.GetXmlAsync(url.GetRecent(page));

    Assert.IsTrue(!string.IsNullOrEmpty(xml));
}

2 个答案:

答案 0 :(得分:5)

在你的应用中,你没有在使用 await 调用this.loader.GetXmlAsync(url)之前你点击这一行,在另一个线程上触发异步任务然后立即进入下一行没有得到回应。它适用于您的单元测试,因为您正确使用等待关键字。

答案 1 :(得分:4)

causing a deadlock同步阻止任务结果。

遵循以下最佳做法:

  • 请勿阻止async代码(让它async一直向下)。

    例如,var xml = await this.loader.GetXmlAsync(url);中的GetRecentAsync

  • 如果可以在线程池线程上继续使用“库”ConfigureAwait(false)方法中的async

    例如var response = await httpClient.GetAsync(uri).ConfigureAwait(false);中的xml = await response.Content.ReadAsStringAsync().ConfigureAwait(false);GetXmlAsync