HttpClient.GetAsync (…) gibt bei Verwendung von await / async niemals zurück

Bearbeiten: Diese Frage sieht aus wie es das gleiche Problem sein könnte, hat aber keine Antworten ...

Bearbeiten: Im Testfall 5 scheint die Aufgabe festzusteckenWaitingForActivation Zustand.

Ich habe mit dem System.Net.Http.HttpClient in .NET 4.5 ein merkwürdiges Verhalten festgestellt, bei dem auf das Ergebnis eines Aufrufs von (z. B.) gewartet wurde.httpClient.GetAsync(...) Ich werde niemals zurückkehren.

Dies tritt nur unter bestimmten Umständen auf, wenn die neue Async / Warten-Sprachfunktionalität und die Aufgaben-API verwendet werden. Der Code scheint immer zu funktionieren, wenn nur Fortsetzungen verwendet werden.

Hier ist ein Code, der das Problem reproduziert: Legen Sie diesen in einem neuen "MVC 4 WebApi-Projekt" in Visual Studio 11 ab, um die folgenden GET-Endpunkte verfügbar zu machen:

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

Jeder der Endpunkte hier gibt dieselben Daten zurück (die Antwortheader von stackoverflow.com), mit Ausnahme von/api/test5 was nie abgeschlossen ist.

Habe ich einen Fehler in der HttpClient-Klasse festgestellt oder nutze ich die API auf irgendeine Weise falsch?

Zu reproduzierender Code:

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

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

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

    /// <summary>
    /// Retrieves data using async/await
    /// </summary>
    protected async Task<string> 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
{
    /// <summary>
    /// Handles task using Async/Await
    /// </summary>
    public async Task<string> Get()
    {
        var data = await Continuations_GetSomeDataAsync();

        return data;
    }
}

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

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

        return data;
    }
}

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

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

        return data;
    }
}

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

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

        return data;
    }
}

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

Antworten auf die Frage(5)

Ihre Antwort auf die Frage