【问题标题】:HttpContext is lost in background threadHttpContext 在后台线程中丢失
【发布时间】:2021-03-24 11:57:14
【问题描述】:

我有一个异步方法,它使用 HttpContext.Current,它被另一个在后台运行的代码使用,比如

var result = Task.Run(async () => await SomeMethod()).Result;

HttpContext.Current 始终为 null。 有没有办法将 HttpContext 传递给后台任务?

【问题讨论】:

  • 听起来好像以前被引用过:stackoverflow.com/questions/8925227/…
  • 最近的stackoverflow.com/questions/63413283/… ....根据答案有一种方法可以做到这一点,但这是不可取的,因为 HttpContext 不是线程安全的。
  • 如果它真的是一个“后台任务”,那么为什么它首先需要访问 HttpContext 呢?后台任务的整个想法是它发生在 HttpContext 之外。
  • 我将它作为后台任务启动以防止死锁。
  • 那你找错树了。在大多数情况下,如果您使用 .Result、Task.Run 或 .Wait(),这些都是强烈的迹象,表明您需要仔细检查异步模式。如果你想调用一个异步方法,在大多数情况下你应该只是await它。

标签: c# asp.net async-await task-parallel-library httpcontext


【解决方案1】:

有没有办法将 HttpContext 传递给后台任务?

技术上是的,你可以设置HttpContext.Current。但是,您真的不想这样做。 HttpContext 一次只能由一个线程使用。

更好的解决方案是完全删除Task.Run

await SomeMethod();

Task.Run shouldn't be used on ASP.NET in the first place.

看起来该代码可能试图使用Task.Run 执行“一劳永逸”,在这种情况下Task.Run 是一个非常危险且不完整的“解决方案”。正确的“即发即弃”解决方案是asynchronous messaging,即具有单独后台服务的持久队列。

【讨论】:

  • 抱歉,我更新了我的代码,因为我正在返回结果。如果我这样做 (await SomeMethod()).Result,那么这似乎永远挂起。
  • Don't block on asynchronous code;使用async all the way。换句话说,使用await 而不是Result
  • 由于我们使用的框架,这是不可能的。我应该一直同步吗?不过,我们正在进行的 http 调用会阻塞 ui 一段时间。
  • @user2820173 由于框架,您是什么意思?您认为哪个框架可以防止异步?无论哪种方式,UI 都会在此处被阻止,除非您真正在后台运行(无法访问 HttpContext)。 ASP.NET 与 Windows 窗体等桌面编程的方式不同。一旦所有服务器端代码都执行完毕(后台工作除外),HTTP 响应将被发送到客户端浏览器,此时客户端可以重新呈现自己。
  • @user2820173:那你应该一直同步。
猜你喜欢
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 2019-03-11
  • 2011-02-09
  • 2012-04-14
相关资源
最近更新 更多