4

我有一个 Asp.Net 应用程序,它使用 svcutil 生成的代理调用一些 WCF 服务。生成的代理在 APM 模式中具有异步方法(BeginXxx、EndXxx)。

我正在使用异步目标包以利用新async/await模式,并且我的目标平台是 .net 4.0(否则我不必使用异步目标包)。

我正在使用Task<T>.Factory.FromAsync将 APM 模式转换为我可以等待的任务。

我的代码看起来有点像这样(假设服务方法不带参数并返回一个 int:

int result = await Task<int>.Factory.FromAsync(proxy.BeginXxx, proxy.EndXxx, state: null);
HttpContext.Current.Items["reuslt"] = result;

第二行抛出一个NullReferenceException.

我假设原因是回调(这是等待调用之后运行的所有内容)没有原始同步上下文。

其他方法(如 Factory.StartNew)具有接收可用于保留上下文的重载。TaskScheduler

FromAsync 方法还具有接收 a 的重载TaskScheduler,但没有一个具有 begin 方法作为参数的重载。

假设我不想开始手动将 Http 上下文作为方法参数传递给在此行之后调用的所有方法,我如何使用获取任务调度程序的重载或以其他方式获取 .Net 来尊重我的同步上下文?

4

1 回答 1

5

我怀疑问题实际上出在 ASP.NET 管道中,而不是SynchronizationContext.

Async Targeting Pack 启用async/await支持,但在 ASP.NET 4.5 中进行了很多更改以使其async友好,并且 Targeting Pack 不包括该支持。

RegisterAsyncTask尝试通过使用(用于 Web 表单)或AsyncManager(用于 MVC)来帮助 ASP.NET 管道。即使这样,管道中的某些地方也不能采用异步代码(在 ASP.NET 4.5 中仍然如此,但至少 4.5 会检测到这一点并引发错误)。

于 2012-08-19T19:40:29.983 回答