【问题标题】:HttpContext.Current null inside async task异步任务中的 HttpContext.Current null
【发布时间】:2013-10-07 07:40:20
【问题描述】:

我有一个使用存储库的方法 (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;
    }

userRepoobject 有一个使用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 不会为空?

【问题讨论】:

  • “如何确保HttpContext.Current 不会为空?”根本不要使用Tasks 或async-await。在这种情况下,它并没有改善任何东西。
  • @svick 好吧,await 至少可以识别 http-context;这里的问题是Task.Start 不是。

标签: c# ninject async-await httpcontext


【解决方案1】:

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

基本上,通过对工作人员执行此操作,您(在此过程中,因此)将该工作人员从 http-context 中分离出来。您必须:

  • 从 http-context 中获取您需要的信息并将其传递给 worker,或者
  • 不要使用工人

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

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

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

在哪里-因为您现有的代码可能并行执行,即

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

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

【讨论】:

    猜你喜欢
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2018-07-27
    • 2017-09-30
    • 1970-01-01
    相关资源
    最近更新 更多