web-dev-qa-db-ja.com

HttpClient PostAsyncとSendAsyncの違い

WPFフロントエンドのプロジェクトで作業し、HttpClientへの非同期呼び出しのハンドルを取得しようとしていますが、PostAsyncを機能させるために何度も試行錯誤してきましたが、定期的にデッドロック、または少なくともポスト応答のように見えますタイムアウトの値が大きくても、タイムアウトが発生し、フィドラーで応答が表示されます。

しばらくしてから、HttpClientで他のいくつかのメソッドを試してみることにしましたが、最初に試してみました。なぜだかわかりません。

awaitsasyncs、および.ConfigureAwait(false)を使用して、WPFボタンまで完全にクリーンアップします(私はそう思います)。

ボタン:

private async void Generate_Suite_BTN_Click(object sender, RoutedEventArgs e)
{
    await suiteBuilder.SendStarWs().ConfigureAwait(false);
}

XmlDocロード:

internal async Task SendStarWs()
{
    var xmlDoc = new XmlDocument();
    xmlDoc.Load("C:\\Temp\\file.xml");
    await StarWSClient.SendStarMessage(xmlDoc).ConfigureAwait(false);
}

メッセージを送る:

private static readonly HttpClient Client = new HttpClient {MaxResponseContentBufferSize = 1000000};

public static async Task<STARResult> SendMessage(vars)
{
var response = await SendRequestAsync(url, contentNew, Client).ConfigureAwait(false);
return new STARResult(response, hash);
}

これは私のエンドポイントに対してすぐに '500s'を呼び出します。

var response = await SendRequestAsync(url, contentNew, Client).ConfigureAwait(false);

private static async Task<HttpResponseMessage> SendRequestAsync(string adaptiveUri, StringContent content, HttpClient httpClient)
{
    HttpResponseMessage responseMessage = null;
    try
    {
        responseMessage = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Post, adaptiveUri)).ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        if (responseMessage == null)
            responseMessage = new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.InternalServerError,
                ReasonPhrase = $"SendRequestAsync failed: {ex.Message}"
            };
    }
    return responseMessage;
}

Postバリアントは、タイムアウト値に関係なくタイムアウトメッセージを含むTaskCancellationExceptionを返します。

var response = await PostRequestAsync(url, contentNew, Client).ConfigureAwait(false);

private static async Task<HttpResponseMessage> PostRequestAsync(string adaptiveUri, StringContent content, HttpClient httpClient)
{
    HttpResponseMessage responseMessage = null;
    try
    {
        responseMessage = await httpClient.PostAsync(adaptiveUri, content).ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        if (responseMessage == null)
            responseMessage = new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.InternalServerError,
                ReasonPhrase = $"PostRequestAsync failed: {ex.Message}"
            };
    }
    return responseMessage;
}

私のエンドポイントは他のソフトウェアに正常に応答するので、エンドポイントがしっかりしていると確信しています。送信がブロックされていないのに、なぜポスト応答がブロックされているのか理解できません。

4
Ian Moriarty

SendAsyncは、そのプロパティの設定方法に応じて、任意のhttp動詞要求を行うことができます。 PostAsyncおよび類似のメソッドは、単なる便利なメソッドです。これらの便利なメソッドは内部でSendAsyncを使用するため、ハンドラーを派生するときに、すべての送信メソッドではなくSendAsyncをオーバーライドするだけで済みます。

ただし、他の質問へ:SendAsyncを使用する場合は、コンテンツを作成して渡す必要があります。空のメッセージを送信するだけです。 500は、APIがモデルバインディングからnullを取得し、元に戻したことを意味します。 @Johnがコメントしたとおり。

12
JSteward