You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExecutionContext是否始终流入Task.Run/Parallel.ForEach?ASP.NET请求对象疑问

ASP.NET中嵌套Task.Run/Parallel.ForEach时Request对象的访问问题

我在ASP.NET应用的控制器中大量嵌套使用Task.Run和Parallel.ForEach,层级有时达到2-3层,代码结构如下:

// 此代码位于控制器中(即Request对象处于作用域内)
Task.Run(() => {
  Parallel.ForEach(things, t => {
    Task.Run(() => {
      Parallel.ForEach(otherThings, t => {
// 等等..

我清楚这种写法并不规范,但我的疑问是:Request对象是否应该能在整个嵌套层级中被访问到?

我查阅资料了解到,ExecutionContext会自动流转到这些异步/并行代码中(除非显式阻止),第一个Task.Run应该会获取和外部代码相同的ExecutionContext,并传递给后续的Parallel.ForEach等,理论上嵌套最深处的代码应该能访问到原调用代码的相同数据。

但实际场景中,我在某些层级遇到了奇怪的空引用错误:Task.Run内部的对象为空,而外部代码中该对象不为空,且错误只出现在特定代码里,我找不到差异点。我是不是误解了ExecutionContext流转的某些细节?


更新:问题根源确认

根据测试验证,问题出在未使用async/await等待任务完成,导致请求已经结束、Request对象被销毁后,后台任务才开始执行,此时自然无法访问到Request相关对象。

可正常运行的测试代码(无限循环)

[Route("test")]
public async Task<string> Test()
{
    await Task.Run(() =>
    {
        var counter = 0;
        while (true)
        {
            counter++;
            ServiceLocator.Current.GetInstance<IHttpContextAccessor>().HttpContext.Items.Add(counter.ToString(), "foo");
            Debug.WriteLine(counter);
        }

    });

    return "OK";
}

无法运行的测试代码(抛出空引用异常)

[Route("test")]
public string Test()
{
    Task.Run(() =>
    {
        var counter = 0;
        while (true)
        {
            counter++;
            ServiceLocator.Current.GetInstance<IHttpContextAccessor>().HttpContext.Items.Add(counter.ToString(), "foo");
            Debug.WriteLine(counter);
        }

    });

    return "OK";
}

内容的提问来源于stack exchange,提问作者Deane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:42:07