我是一个webApi操作,它在||中执行2个操作在内部调用HttpClient sendAsync。如果我应用调试器并执行调用,它将工作并返回。如果我删除调试器,两个异步调用仍然有效(在Fiddler中检查)但WebApi操作的调用者没有得到任何响应(使用AdvanceRest chrome插件)。从其他线程,我可能没有正确使用async / await并且与ASP.NET synchronizationContext相关
//**WEB API Controller***
class SomeController
{
public HttpResponseMessage Get()
{
Client someClient = new Client();
aResponse = new aResponse();
bResponse = new bResponse();
Parallel.Invoke(
() => {aResponse = someClient.a()},
() => {bResponse = someClient.b()});
var response = {a=aResponse, b=bResponse};
return Response.Create(OK, response}
}
class SomeClient
{
AResponse a()
{
var clientResponse = ClientMgr.Execute("url");
return new AResponse {HttpClientResponse = clientResponse.Result}
}
BResponse b()
{
var clientResponse = ClientMgr.Execute("url");
return new BResponse {HttpClientResponse = clientResponse.Result}
}
}
//Utility CLASS
public class ClientMgr
{
public static async Task<HttpResponseMessage> Execute(string url)
{
request = new HttpRequestMessage();
//....request fill
HttpClient client = new HttpClient();
var response = await client.SendAsync(request);
client.dispose();
return response;
}
}
public class AResponse
{
HttpResponseMessage HttpClientResponse {get;set;}
// Some other properties....
}
为什么操作会在我使用断点时返回响应,但是当我删除它们时,它不会返回响应?
答案 0 :(得分:3)
您的问题(除了您发布的代码无法编译的事实)是您在调试时,异步操作实际上已完成。当您不进行调试时,他们不会,并且会返回Task<YourResponse>
,而不是Task
的实际结果。
为了使其正常工作,请将您的方法标记为async
并使用Task.WhenAll
异步等待这两项任务:
[HttpGet]
public async Task<HttpResponseMessage> GetAsync()
{
Client someClient = new Client();
var aTask = someClient.AAsync();
var bTask = someClient.BAsync();
await Task.WhenAll(aTask, bTask);
var response = { a = aTask.Result, b = bTask.Result };
return Response.Create(OK, response}
}
附注 - 当您进行IO绑定操作时,您不需要使用Paralle.Invoke
。这些是冗余线程,将被阻止等待IO的完成。