C# 控件在调用异步WebAPI后不会返回等待的webClient
我们有一个Restful客户机-服务器环境,我正在尝试调试我的代码,其中客户机代码如下所示:C# 控件在调用异步WebAPI后不会返回等待的webClient,c#,asynchronous,asp.net-web-api,task-parallel-library,swagger,C#,Asynchronous,Asp.net Web Api,Task Parallel Library,Swagger,我们有一个Restful客户机-服务器环境,我正在尝试调试我的代码,其中客户机代码如下所示: await Client.DoWork(Id); public virtual async Task<IActionResult> DoWork(long Id) { return Ok(); } 而服务器代码如下所示: await Client.DoWork(Id); public virtual async Task<IActionResult> Do
await Client.DoWork(Id);
public virtual async Task<IActionResult> DoWork(long Id)
{
return Ok();
}
而服务器代码如下所示:
await Client.DoWork(Id);
public virtual async Task<IActionResult> DoWork(long Id)
{
return Ok();
}
这就是控制消失的地方
- 这里有一点可能有用,也可能没有帮助,那就是服务调用是通过代理进行的。不确定这是否会改变什么
当客户机调用API时,我可以看到它转到
Return OK()
,我在Fiddler中看到它确实返回了200OK,但控件从未返回到调用方法。如何解决这个问题?您已经发现在控制台应用程序中向异步方法添加.Wait()
可以解决这个问题。这里有一个关于这个问题的好答案。答案中提到的那篇文章
当等待运算符被传递一个不完整的任务时。。。然后,默认情况下,wait将捕获当前上下文并从方法返回一个未完成的任务
所以,基本上当客户端启动异步通信时,服务器方法返回未完成的任务。而且,因为在客户端从服务器获得响应之前,Main
methodconsole应用程序不会等待它退出
控制台应用程序中没有
SynchronizationContext
,因此可以安全地使用.Wait()
方法或.Result
属性阻止Main
方法中的线程,直到异步操作完成。这通常意味着死锁。自然取决于环境。例如,您的客户端可能是UI应用程序(如WPF或win forms)或asp.net应用程序,您可以在堆栈的某个位置执行类似于Task.Wait或Tadk.Result的操作。这是一个webClient,我们正在将swagger与ConfigureWait(false)
一起使用。我认为它应该足够了。如果你从asp.net应用程序调用它,上面的仍然适用。如果没有更多的代码和信息(客户机到底是什么,它如何调用api,在client.DoWork中是什么,等等),很难说出更多。死锁在客户机上,而不是服务器上,所以只有客户机代码相关。目前还不清楚什么是客户端应用程序。我知道您是大摇大摆地生成api代码的,但您是从哪个应用程序使用该api的?正如@Evk提到的,服务器代码与此无关,特别是如果您可以在Fiddler中看到响应正在返回。这是客户的问题。仅仅因为SendAsync
行具有ConfigureAwait(false)
并不意味着堆栈的其余部分是好的。常见的罪魁祸首是.Wait()。