【发布时间】:2017-11-29 04:31:01
【问题描述】:
在 ASP.NET Core 中,我使用IHttpContextAccessor 来访问当前的HttpContext。 HttpContextAccessor uses AsyncLocal<T>.
在一种情况下,我试图从请求中启动Task,它应该在请求结束后继续运行(长时间运行,后台任务),并且我试图将它与当前执行上下文分离这样IHttpContextAccessor 返回null(否则我访问的是无效的HttpContext)。
我尝试了Task.Run、Thread.Start,但每次,上下文似乎都会延续,IHttpContextAccessor 无论我尝试什么都会返回旧上下文(有时甚至是来自其他请求的上下文????)。
如何启动具有干净 AsyncLocal 状态的任务,以便 IHttpContextAccessor 返回 null?
【问题讨论】:
-
无论如何,您都应该避免在 ASP.NET Core 中运行/生成自己的线程/后台任务,这会扰乱 ASP.NET Core 处理传入请求的线程的方式。您应该使用一种本地或远程消息总线正确执行此操作,并让真正的后台进程(即不托管 asp.net 核心的控制台应用程序)处理它
-
至少我应该能够创建自己的线程而不会干扰 Kestrel 的请求处理。即使这样也不起作用,并捕获了一些随机的
HttpContext。 -
Task.Run(...)等有一个参数可以设置调度器。您可以在此处设置默认调度程序(ASP.NET Core 运行自己的调度程序),即Task.Run(() => DoSomething(), TaskScheduler.Default)。但同样,我不建议您这样做,您应该考虑如上所述的真实后台进程,因为后台任务所占用的线程是不能用于接受请求的线程。 ASP.NET Core 应该只使用await/async进行真正的异步操作,而不是 CPU 密集型的东西或后台任务 -
也是有用的资源hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspxhaacked.com/archive/2011/10/16/…,虽然它主要是关于 ASP.NET 4,但它的概念仍然适用
-
我没有使用 IIS。与 IIS 不同,Kestrel 不回收其 AppDomain(事实上,它根本没有 AppDomain)。无论如何,在我的用例中,被中断的后台任务都不是问题。同样,
Thread.StartNew产生了一个并非来自线程池的全新线程,因此您之前的评论是题外话。
标签: asp.net-core .net-core asp.net-core-1.1