gpt4 book ai didi

c# - 异步任务中的 HttpContext.Current null

转载 作者:可可西里 更新时间:2023-11-01 08:41:23 24 4
gpt4 key购买 nike

我有一个使用存储库的方法 (userRepo):

    public override Task<IdentityResult> CreateLocalUserAsync(IUser user, string password, CancellationToken cancellationToken)
{
var task = new Task<IdentityResult>(() => {

TUserEntity newUser = new TUserEntity
{
Id = user.Id,
UserName = user.UserName,
Password = password
};

userRepo.Save(newUser).Flush();

return new IdentityResult(true);
}, cancellationToken);

task.Start();

return task;
}

userRepo 对象具有使用 HttpContext.Current 的依赖项。这两个都是使用 ninject InRequestScope 解决的。

上述方法在 Mvc 5 的默认 AccountController 中调用:

var result = await IdentityManager.Users.CreateLocalUserAsync(user, model.Password);

我已经尝试将此设置添加到 web.config 中:

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

此外,我肯定在使用 .NET 4.5。这也在我的 web.config 中:

<httpRuntime targetFramework="4.5" />

在开始任务之前无法从 HttpContext 获取信息,因为任务中 userRepo 的依赖项正在使用该信息,并且两个对象都是使用 Ninject 解决。

如何确保 HttpContext.Current 不会为空?

最佳答案

此处的“任务友好同步上下文”适用于 await 的延续:无论您对 result 做什么,它都将具有 http 上下文。但是,它task.Start 相关。这涉及到 TaskScheduler ,而不是同步上下文。

基本上,通过对工作人员执行此操作,您(在这个过程中,结果)使该工作人员与 http 上下文分离。您必须:

  • 从 http 上下文中获取您需要的信息并将其传递给 工作人员,或者
  • 不要使用 worker

就个人而言,我怀疑将其推给工作人员是否会获得很多好处。如果你真的想使用 async,理想的情况是你的 repo 在内部支持 *Async 方法。这需要的不仅仅是使用线程:它通常意味着架构更改,例如,使用异步 SQL 方法。从头开始编写的使用 async 和同步上下文感知延续(aka await)的东西会自动保留诸如 http 上下文之类的东西。

这里的重要区别是 async/await 实现是线性的但不是连续的,即

 <===(work)==>
<===(callback; more work)===>
<===(another callback)===>

因为您现有的代码可能并行执行,即

<==========(original work)=================>
<===========(task on worker thread)=============>

async/await 方法基本上是线性的,这使得它更适合访问诸如 http-context 之类的东西,因为它知道(做对了)一次只会有一个线程访问它——即使它不是端到端的同一个线程。

关于c# - 异步任务中的 HttpContext.Current null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19111218/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com