HttpClient.GetAsync(…) никогда не возвращается при использовании await/async

Изменить:Этот вопрос выглядит так, как будто это та же проблема, но нет ответов...

Изменить: В тестовом примере 5 задача зависла в состоянии WaitingForActivation.

Я столкнулся со странным поведением при использовании System.Net.Http.HttpClient в .NET 4.5, где «ожидание» результата вызова (например) httpClient.GetAsync(...)никогда не вернется.

Это происходит только при определенных обстоятельствах при использовании новых функций языка async/await и Tasks API — кажется, что код всегда работает при использовании только продолжений.

Вот некоторый код, который воспроизводит проблему — поместите его в новый «проект MVC 4 WebApi» в Visual Studio 11, чтобы предоставить следующие конечные точки GET:

/api/test1
/api/test2
/api/test3
/api/test4
/api/test5 <--- never completes
/api/test6

Каждая из конечных точек здесь возвращает одни и те же данные (заголовки ответов из stackoverflow.com), за исключением /api/test5, который никогда не завершается.

Обнаружена ли ошибка в классе HttpClient или я неправильно использую API?

Код для воспроизведения:

public class BaseApiController : ApiController
{
    /// 
    /// Retrieves data using continuations
    /// 
    protected Task Continuations_GetSomeDataAsync()
    {
        var httpClient = new HttpClient();

        var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);

        return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString());
    }

    /// 
    /// Retrieves data using async/await
    /// 
    protected async Task AsyncAwait_GetSomeDataAsync()
    {
        var httpClient = new HttpClient();

        var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);

        return result.Content.Headers.ToString();
    }
}

public class Test1Controller : BaseApiController
{
    /// 
    /// Handles task using Async/Await
    /// 
    public async Task Get()
    {
        var data = await Continuations_GetSomeDataAsync();

        return data;
    }
}

public class Test2Controller : BaseApiController
{
    /// 
    /// Handles task by blocking the thread until the task completes
    /// 
    public string Get()
    {
        var task = Continuations_GetSomeDataAsync();

        var data = task.GetAwaiter().GetResult();

        return data;
    }
}

public class Test3Controller : BaseApiController
{
    /// 
    /// Passes the task back to the controller host
    /// 
    public Task Get()
    {
        return Continuations_GetSomeDataAsync();
    }
}

public class Test4Controller : BaseApiController
{
    /// 
    /// Handles task using Async/Await
    /// 
    public async Task Get()
    {
        var data = await AsyncAwait_GetSomeDataAsync();

        return data;
    }
}

public class Test5Controller : BaseApiController
{
    /// 
    /// Handles task by blocking the thread until the task completes
    /// 
    public string Get()
    {
        var task = AsyncAwait_GetSomeDataAsync();

        var data = task.GetAwaiter().GetResult();

        return data;
    }
}

public class Test6Controller : BaseApiController
{
    /// 
    /// Passes the task back to the controller host
    /// 
    public Task Get()
    {
        return AsyncAwait_GetSomeDataAsync();
    }
}

297
задан Community 23 May 2017 в 02:18
поделиться