gpt4 book ai didi

ASP.NET HttpContext.Current 在 Task.Run 中

转载 作者:行者123 更新时间:2023-12-03 22:22:57 28 4
gpt4 key购买 nike

我有一个在 ASP.NET MVC 应用程序中使用的以下代码示例。
这段代码的目的是创建“即发即忘”的请求来排队一些长时间运行的操作。

public JsonResult SomeAction() {
HttpContext ctx = HttpContext.Current;

Task.Run(() => {
HttpContext.Current = ctx;
//Other long running code here.
});

return Json("{ 'status': 'Work Queued' }");
}

我知道这不是在异步代码中处理 HttpContext.Current 的好方法,但目前我们的实现不允许我们做其他事情。
我想了解这段代码有多危险......

问题:从理论上讲,在 Task.Run 中设置 HttpContext 是否可能将上下文设置为完全另一个请求?

我想是的,但我不确定。我是怎么理解的:
Request1 由线程池中的 Thread1 处理,然后当 Thread1 处理绝对另一个请求(Request2)时,Task.Run 中的代码会将上下文从 Request1 设置为 Request2。

也许我错了,但我对 ASP.NET 内部结构的了解不允许我正确理解它。

谢谢!

最佳答案

让我在你身上撞上一点内部结构:

public static HttpContext Current
{
get { return ContextBase.Current as HttpContext; }
set { ContextBase.Current = value; }
}

internal class ContextBase
{
internal static object Current
{
get { return CallContext.HostContext; }
set { CallContext.HostContext = value; }
}
}

public static object HostContext
{
get
{
var executionContextReader = Thread.CurrentThread.GetExecutionContextReader();
object hostContext = executionContextReader.IllogicalCallContext.HostContext;
if (hostContext == null)
{
hostContext = executionContextReader.LogicalCallContext.HostContext;
}
return hostContext;
}
set
{
var mutableExecutionContext = Thread.CurrentThread.GetMutableExecutionContext();
if (value is ILogicalThreadAffinative)
{
mutableExecutionContext.IllogicalCallContext.HostContext = null;
mutableExecutionContext.LogicalCallContext.HostContext = value;
return;
}
mutableExecutionContext.IllogicalCallContext.HostContext = value;
mutableExecutionContext.LogicalCallContext.HostContext = null;
}
}

所以
var context = HttpContext.Current;

等于(伪代码)
var context = CurrentThread.HttpContext;

并在您的 Task.Run 内发生这样的事情
CurrentThread.HttpContext= context;
Task.Run将使用线程池中的线程启动新任务。所以你说你的新线程“HttpContext 属性”是对起始线程“HttpContext 属性”的引用 - 到目前为止一切顺利(以及你在起始线程完成后将面临的所有 NullReference/Dispose 异常)。问题是如果在你的
//Other long running code here.

你有这样的声明
var foo = await Bar();

一旦你点击 await,你当前的线程将返回到线程池,IO 完成后你从线程池中获取新线程 - 想知道它的“HttpContext 属性”是什么,对吧?我不知道 :) 很可能你会以 NullReferenceException 结束。

关于ASP.NET HttpContext.Current 在 Task.Run 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39704409/

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