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

我猜我需要在第二次等待之前同步一些东西,但我不确定。

HTTPContext中的多个等待场景

你的代码肯定应该工作。我假设既然你提到MVC 3,这是一个升级的项目。在这种情况下,请确保您在web.config中有以下内容:

<appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>