如何 return 将 HttpClient 响应异步返回给 WinForm?

How to return async HttpClient responses back to WinForm?

到目前为止,我一直在 WinForms 应用程序中进行同步 HttpWebRequest 调用。我想开始异步执行它,以免阻塞 UI 线程并让它挂起。因此,我正在尝试切换到 HttpClient,但我也是异步和任务的新手,还不太了解它。

我可以启动请求并获得响应并隔离我想要的数据(结果、reasonPhrase、headers、代码),但不知道如何取回它以在 textBox1 中显示。如果发生超时或无法连接消息,我还需要将 ex.message 和 return 捕获到表单中。

我看到的每个示例都在可用时将值写入 Console.WriteLine(),但我需要将它们 return 返回到表单以进行显示和处理,并有一个很难理解如何。

这是一个简单的例子:

namespace AsyncHttpClientTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = "calling Test()...\r\n";
            DownloadPageAsync();

            // need to get from DownloadPageAsync here: result, reasonPhrase, headers, code 

            textBox1.AppendText("done Test()\r\n");
        }
        static async void DownloadPageAsync()
        {
            // ... Use HttpClient.
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    using (HttpResponseMessage response = await client.GetAsync(new Uri("http://192.168.2.70/")))
                    {
                        using (HttpContent content = response.Content)
                        {
                            // need these to return to Form for display
                            string result = await content.ReadAsStringAsync();
                            string reasonPhrase = response.ReasonPhrase;
                            HttpResponseHeaders headers = response.Headers;
                            HttpStatusCode code = response.StatusCode;
                        }
                    }
                }
                catch (Exception ex)
                {
                    // need to return ex.message for display.
                }
            }
        }
    }
}

有什么有用的提示或建议吗?

创建一个模型来保存您想要的数据return

public class DownloadPageAsyncResult {
    public string result { get; set; } 
    public string reasonPhrase { get; set; } 
    public HttpResponseHeaders headers { get; set; }
    public HttpStatusCode code { get; set; }
    public string errorMessage { get; set; }
}

避免使用 async void 方法。将方法转换为 async Task 并在允许的事件处理程序中调用它。

private async void button1_Click(object sender, EventArgs e) {
    textBox1.Text = "calling Test()...\r\n";
    var result = await DownloadPageAsync();

    // Access result, reasonPhrase, headers, code here

    textBox1.AppendText("done Test()\r\n");
}

static HttpClient client = new HttpClient();
static async Task<DownloadPageAsyncResult> DownloadPageAsync() {
    var result = new DownloadPageAsyncResult();
    try {
        using (HttpResponseMessage response = await client.GetAsync(new Uri("http://192.168.2.70/"))) {
            using (HttpContent content = response.Content) {
                // need these to return to Form for display
                string resultString = await content.ReadAsStringAsync();
                string reasonPhrase = response.ReasonPhrase;
                HttpResponseHeaders headers = response.Headers;
                HttpStatusCode code = response.StatusCode;                    

                result.result = resultString;
                result.reasonPhrase = reasonPhrase;
                result.headers = headers;
                result.code = code;
            }
        }
    } catch (Exception ex) {
        // need to return ex.message for display.
        result.errorMessage = ex.Message;
    }
    return result;
}

也不应该在每次调用下载时都创建HttpClient

参考