HTTPContext中的多个等待场景
本文关键字:等待 HTTPContext | 更新日期: 2023-09-27 18:10:17
我正在编写一些MVC4异步控制器代码,并且我正在获得一个问题,即我异步调用两个长时间运行的web服务,第二个调用似乎是在错误的线程上。
下面是代码片段:public async Task<ActionResult> AmendDetails(Model model)
{
ClientMaintenanceClient clientService = new ClientMaintenanceClient();
UpdateResponse clientResponse = await clientService.GetForUpdateAsync(clientService.CreateRequest(model.Id));
StaticDataEnquiryClient staticService = new StaticDataEnquiryClient();
DataResponse staticResponse = await staticService.GetPayMethodsAsync(staticService.CreateRequest());
...
}
本质上,对CreateRequest()的调用将从HttpContext中查找会话id,并创建一个形成的WCF请求对象,用于对服务的调用。
在执行然而,第一次调用发生良好,然而第二次异步调用失败,因为HttpContext是空的,这将导致我相信我现在在一个不同的线程。
当我在MVC3中这样做时,在. net 4.5之前,我必须通过AsyncManager(使用EAP)从Async调用返回时手动同步线程,但我认为我不再需要使用TAP。
如果我使用下面的代码片段并行执行代码,问题就会消失。
public async Task<ActionResult> AmendDetails(Model model)
{
ClientMaintenanceClient clientService = new ClientMaintenanceClient();
var clientTask = clientService.GetForUpdateAsync(clientService.CreateRequest(model.Id));
StaticDataEnquiryClient staticService = new StaticDataEnquiryClient();
var staticTask = staticService.GetPayMethodsAsync(staticService.CreateRequest());
await Task.WhenAll(clientTask,staticTask);
UpdateResponse clientResponse = await clientTask;
DataResponse staticResponse = await StaticTask;
...
}
我假设在第一个代码片段中,第一个await将进程移动到后台线程上,因此当我到达第二个await时,我仍然在后台线程上。HttpContext将为空,因为我无法从那个线程访问它
我也假设在代码的第二个片段中,我在第一次等待之前做所有的HTTPContext查找,所以我从来没有看到HTTPContext为空,因为我从来没有从后台线程调用它。
更新:
我决定在执行过程中检查线程,看起来第二次等待确实发生在与第一次等待不同的线程上。有趣的是,似乎在第二次调用时HttpContext不是空的。它是HttpContext。当前为空。
我正在访问会话id:
HttpContext.Current.Session.SessionId
我猜我需要在第二次等待之前同步一些东西,但我不确定。
你的代码肯定应该工作。我假设既然你提到MVC 3,这是一个升级的项目。在这种情况下,请确保您在web.config中有以下内容:
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>