来自Web UI的死锁.Result

Rag*_*hav 0 .net c# asp.net async-await

我正在阅读以下主题http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

并决定在我的库中编写一个通用的实用工具方法,通过HTTPClient对远程URL进行GET

public static async Task<T> GetAsync<T>(HttpGetObject getObject)
{
    string baseUrl = getObject.BaseUrl;
    string actionUrl = getObject.ActionRelativeUrl;
    string acceptType = getObject.AcceptType;

    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(baseUrl);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(acceptType));

        AddCustomHeadersToHttpClient(client, getObject);

        // HTTP GET
        HttpResponseMessage httpResponseMessage = await client.GetAsync(actionUrl).ConfigureAwait(false);
        if (httpResponseMessage.IsSuccessStatusCode)
        {
            T response = await httpResponseMessage.Content.ReadAsAsync<T>().ConfigureAwait(false);
            return response;
        }
        else
        {
            string message = httpResponseMessage.Content.ReadAsStringAsync().Result;
            throw new Exception(message);
        }
    }
    return default(T);
}
Run Code Online (Sandbox Code Playgroud)

我知道"等待httpResponseMessage.Content.ReadAsAsync().ConfigureAwait(false)"将阻止上述代码中的死锁第一:我的查询是针对"string message = httpResponseMessage.Content.ReadAsStringAsync().结果"行,将.结果是否会导致该行死锁?

第二:如果我从UI调用这样的代码:

public static object DoGet()
{
    // Build getObject
    var task = Utility.GetAsync(getObject);
    task.Wait();
    var response = task.Result;
    return response;
}
Run Code Online (Sandbox Code Playgroud)

这会导致僵局吗?

请注意,我知道要避免乱七八糟的混乱,从UI到DAL的所有方法都必须是async-await但是我现在不能改变所有结构,我此时的目标是调用HttpClient库并做了一些GET操作.

所以我的问题是上面的代码会导致死锁吗?

第三:

是task.Wait(); 甚至在上面的代码中需要?

Mar*_*ell 6

在一般情况下,您应该假设,调用.Result.Wait()任何等待的东西上都是危险的并且可以死锁(除非您是发布任务的库,并且您了解完整的上下文).这是可能的,它会工作在某些特定情况OK,但你应该依赖于这种行为,即使它的作品今天.