在加载表单之前等待异步函数(Http 请求)

Posted

技术标签:

【中文标题】在加载表单之前等待异步函数(Http 请求)【英文标题】:Waiting for an async function(Http request) before a form loads 【发布时间】:2018-06-26 07:04:33 【问题描述】:

我正在编写一个 winform 应用程序,我想发送一个 Http Post 请求并在主表单加载之前获得响应。到目前为止,我遇到以下情况:

如果我这样做,表单加载将发送请求,并且表单将立即加载。请求响应将稍后到达,但同时可以单击表单中的任何按钮(不是理想的)

private async void Form1_Load(object sender, EventArgs e)

    //client is a HttpClient
    //byteContent is a ByteArrayContent
    using (HttpResponseMessage response = await client.PostAsync("theUrl", 
      byteContent))
    
        response.EnsureSuccessStatusCode();
        Trace.WriteLine(response.ToString());
    


所以我把代码改成了这个,我认为表单会在请求响应到达后加载。然而,并非如此,正在发生的事情是:表单出现在响应到达之前,但鼠标显示加载旋转形状,因此表单中的任何按钮都不可用。响应到达后,表单中的按钮变为可用。

这是正确的,但看起来不太好。

private async void Form1_Load(object sender, EventArgs e)

    //client is a HttpClient
    //byteContent is a ByteArrayContent
    var PostTask = client.PostAsync("theUrl", byteContent);
    PostTask.Wait(); //blocking here

    using (HttpResponseMessage response = PostTask.Result)
    
        response.EnsureSuccessStatusCode();
       Trace.WriteLine(response.ToString());
    


做我想做的事情的正确方法是什么:

响应成功到达后只显示表单?

【问题讨论】:

【参考方案1】:

你还没有说你是在使用 WinForms 还是 WPF。

如果是 WinForms,那么一种可能性是引入“加载”表单。它只会有以下文字:

"Please wait..." 

什么的。然后,您可以在通话结束后强制导航到您的主窗体。这还有一个额外的好处,就是让您可以选择处理呼叫未完成的情况。

如果您使用的是 WPF,那么您可以将控件的可见性绑定到 completedloaded 标志(与 Loading - please wait... 进度指示器的可见性相反)。您还应该能够在视图模型中处理此问题;这意味着您不需要将代码放在表单事件中。

我也会避免使用.Wait() 来等待您的任务。更好的方法可能是使用 TaskCompletionSource 之类的东西。

【讨论】:

谢谢。我正在使用winform(现在编辑了问题)。但是关于 WPF 的信息非常感谢 也感谢等待的建议。我会看看然后再回复它【参考方案2】:

为什么在 async 方法中调用 Wait()Result? 您是否看到任何编译器警告?

试试这个:

private async void Form1_Load(object sender, EventArgs e)

    try
    
        this.Enable = false;

        //client is a HttpClient
        //byteContent is a ByteArrayContent

        using (var response = await client.PostAsync("theUrl", byteContent))
        
            response.EnsureSuccessStatusCode();
            Trace.WriteLine(response.ToString());
        
    
    finally
    
        this.Enable = true;
    

【讨论】:

实际上根本没有编译器警告。顺便说一句,这不是我发布并尝试过的代码吗?我打电话给等待是因为我希望表单在响应到来之后加载。使用上面的代码,无需等待响应即可加载表单。 根本没有编译器警告?没有 CS1998? 如果时间过长会怎样? 虽然我还没有考虑超时,但是程序的规范规定如果第一个操作没有成功完成,就不能进行其他操作

以上是关于在加载表单之前等待异步函数(Http 请求)的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS,如何强制异步 for 循环在传递到下一次迭代之前等待 HTTP 请求解决,这样我们就不会收到 EMFILE 错误?

强制量角器的 onPrepare 等待异步 http 请求

如何等待异步函数执行?

AJAX

dva 如何把同步改为异步请求

在 python 中等待之前,不会在异步函数中调用 print 函数