簡體   English   中英

C#HttpClient-PostAsync不返回(即使使用ConfigureAwait)

[英]C# HttpClient - PostAsync doesn't return (even with ConfigureAwait)

我在C#中使用HttpClient感到瘋狂...

我簡化了項目,因此可以輕松復制我的問題。 我要做的就是在后台調用HttpClient.PostAsync而不阻塞我的UI窗口(我正在使用WPF btw)。

這是我的代碼(將代碼限制到最低限度。):必應僅在這里用於不顯示我的私人Web服務,當然可以將其替換為其他所有網站。

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        try {
            MyTextBlock.Text = "Waiting...";

            Uri webUri = new Uri("https://www.bing.com/");
            using (HttpClient client = new HttpClient()) {
                using (HttpResponseMessage response = await client.PostAsync(webUri, new MultipartFormDataContent())) {
                    MyTextBlock.Text = await response.Content.ReadAsStringAsync();                       
                }
            }
        } catch (Exception exc) {
            MessageBox.Show(exc.ToString(), "Unhandled Exception");
        }
    }

當我的UI等待異步發布請求時,它在TextBox中顯示“正在等待”。 當異步請求返回時,它會顯示結果。 什么也不會發生。

因此,這里出現問題,有時PostAsync方法根本不返回...即使超時也被忽略。 當我調試時,它總是可以工作,但是當我嘗試啟動應用程序時,它有時會掛起。 並非總是如此,這並不會使發現錯誤變得容易。 我嘗試了多種方法來異步調用請求,但是每次都遇到相同的問題。

我還閱讀了以下博客,其中涉及異步方法中的阻塞問題,但即使與ConfigureAwait也沒有區別。 http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

我只是可以想象在鎖定主線程的HttpClient異步方法中存在問題,因此會導致此問題。 溫恩我在ConsoleApplication中使用相同的代碼,一切都很好。 我的客戶與目的地之間有一個代理,但這根本不是問題。

有人可以復制這個問題嗎? 我在C#/ WPF和.NET Framework 4.6.1中使用。

您不需要await client.PostAsync(webUri, i_formData)因為調用返回后您對結果不執行任何操作,只需返回Task 更改為此;

public static Task<HttpResponseMessage> BasicRequest(MultipartFormDataContent i_formData)
{
    Uri webUri = new Uri("https://www.bing.com");

    HttpClient client = new HttpClient {
        Timeout = TimeSpan.FromSeconds(1)
    };
    return client.PostAsync(webUri, i_formData);
}

您的Window_Load是事件處理程序。 您可以使它async void ,這是您不必返回Task的唯一時間。 通過使其async ,您可以刪除所有復雜的代碼:

private async void Window_Loaded(object sender, RoutedEventArgs e)
{
    MyTextBlock.Text = "Waiting";
    HttpResponseMessage response = await BasicRequest(new 
    MultipartFormDataContent());
    string test = await response.Content.ReadAsStringAsync();
    this.Close();
}

首先,完全感謝您的幫助,該問題現在似乎已解決。

我必須做三件事才能完成這項工作:

  1. 獲取在整個應用程序生命周期中都使用它的HttpClient實例,因此不再對HttpClient使用。

  2. 不要在Window_Loaded事件中調用PostAsync,這似乎要早一些。 (我仍然不明白為什么...)

  3. 不要使用ConfigureAwait(false)

現在的代碼如下所示:

HttpClient client = new HttpClient();

private async void MyButton_Click(object sender, RoutedEventArgs e)
{
    try {
        MyTextBlock.Text = "Waiting...";
        Uri webUri = new Uri("https://www.bing.com/");
        using (HttpResponseMessage response = await client.PostAsync(webUri, new ipartFormDataContent())) {
            MyTextBlock.Text = await response.Content.ReadAsStringAsync();
        }
    } catch (Exception exc) {
        MessageBox.Show(exc.ToString(), "Unhandled Exception");
    }
}

為了在啟動時做到這一點,我不得不做出一件非常糟糕的事情。 但它最終可以工作:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    DispatcherTimer startupTimer = new DispatcherTimer();
    startupTimer.Tick += new EventHandler((o, a) => {
        MyFunction();
        startupTimer.Stop();
    });
    startupTimer.Interval = TimeSpan.FromSeconds(1);
    startupTimer.Start();
}

當有人可以復制這些行為或可以解釋為什么發生這種情況時,請在此處進行評論:)


更新資料

問題仍然存在,但似乎僅在客戶端使用某種代理時才存在!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM