我在一个ASP.NET WebForms网站上有服务器端的点击事件。在此事件中,我调用一个方法,该方法又调用其异步伙伴方法,并在调用上添加了
然后,这个方法会进一步调用多层异步方法(例如,调用另一个异步方法,该方法又调用另一个异步方法,以此类推),最终在HttpClient对象上调用异步方法。此时,线程似乎消失在了兔子洞里;该方法从未回调。
现在,我知道异步调用序列按预期工作,因为相同的代码也从Web API控制器调用(控制器方法调用第一个方法的异步版本,而不是同步的“伙伴”方法),它按预期返回。
所以基本上我有像这样的东西,但它永远不会返回。
我发现如果将第一个版本改为以下内容,它就可以工作:
但我不知道为什么。
有人能解释一下调用之间的区别吗?
并调用
.Wait()
。然后,这个方法会进一步调用多层异步方法(例如,调用另一个异步方法,该方法又调用另一个异步方法,以此类推),最终在HttpClient对象上调用异步方法。此时,线程似乎消失在了兔子洞里;该方法从未回调。
现在,我知道异步调用序列按预期工作,因为相同的代码也从Web API控制器调用(控制器方法调用第一个方法的异步版本,而不是同步的“伙伴”方法),它按预期返回。
所以基本上我有像这样的东西,但它永远不会返回。
protected void btn_Click(object sender, EventArgs e)
> Class1.DoSomething()
> Class1.DoSomethingAsync.Wait()
...
> await ClassN.Authenticate()
{
await myHttpClient.PostAsync() // never returns
}
我确实尝试在第一个异步方法中使用.ConfigureAwait(false)
,但没有成功。
我还有这个,它确实返回:
Task<IHttpActionResult> MyWebApiMethod()
> await Class1.DoSomethingAsync()
...
> await ClassN.Authenticate()
{
await myHttpClient.PostAsync() // does return
}
我发现如果将第一个版本改为以下内容,它就可以工作:
protected void btn_Click(object sender, EventArgs e)
> Class1.DoSomething()
> Task.Run(async () => await Class1.DoSomethingAsync()).Wait()
...
> await ClassN.Authenticate()
{
await myHttpClient.PostAsync()
}
但我不知道为什么。
有人能解释一下调用之间的区别吗?
Class1.DoSomethingAsync.Wait()
并调用
Task.Run(async () => await Class1.DoSomethingAsync()).Wait()
async void btn_Click
和await Class1.DoSomethingAsync()
? - Zein MakkiTask.Run
,这样会浪费线程。只需按照 @user3185569 建议的更改button_click
事件处理程序的签名即可。 - Fabioasync
在服务器端的WebForms事件上,因为我不知道我可以这样做。谢谢你指出来给我。 - awj