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

时间:2018-06-26 07:04:33

标签: asynchronous async-await dotnet-httpclient

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

如果执行此操作,则表单加载将发送请求,并且表单将立即加载。请求响应将稍后到达,但与此同时,可以单击表单中的任何按钮(不是理想的方法)

    $(document).on('click', '#save_address', function(e){
      $.ajaxSetup({
          headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
         }
     });
      $.ajax({
        type: 'POST',
        url: '/Get_distance',
        data: {
          '_token': $('input[name=_token]').val(),
          'currentadd': $('#postal_code').val(), 
        },
        success: function(data) {
          console.log(data) //console the elements of data
          $('#totaldistance').val(data.distance); 
        }
      });
    });

因此,我将代码更改为此,并且我认为在请求响应到达后将加载表单。但是,与此相反,发生的是:表单在响应到达之前出现,但是鼠标显示了加载旋转的形状,因此表单中的任何按钮都不可用。响应到达后,表单中的按钮将变为可用。

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

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());
    }

}

做我想做的正确方法是什么

响应成功到达后,表单仅显示 吗?

2 个答案:

答案 0 :(得分:1)

您还没有说要使用WinForms还是WPF。

如果使用WinForms,则一种可能性是引入“正在加载”表单。它只包含以下文本:

"Please wait..." 

之类的。通话结束后,您可以强制导航到您的主窗体。这样做的另一个好处是,您可以选择处理呼叫未完成的情况。

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

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

答案 1 :(得分:0)

为什么要用Wait()方法调用Resultasync? 您是否看到过任何编译器警告?

尝试一下:

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;
    }
}