繁体   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