在加载表单之前等待异步函数(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,那么您可以将控件的可见性绑定到 completed
或 loaded
标志(与 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 错误?