在Task.Run中await/async后获取HttpContext.Current为null

问题描述 投票:0回答:1

我想使用 Task.Run 以“即发即忘”的方式执行 C# 中的方法。在 Task.Run 中,每当我使用 wait 执行另一个异步方法时,HttpContext 就会变为 null。请告诉我是否有办法在 Task.Run 中运行异步方法时保留 HttpContext

示例代码:

public virtual async Task AddAsync(TModel item)
        {
            
            // Copy HttpContext to use in Task.Run
            var httpRequest = HttpContext.Current?.Request;
            var httpResponse = HttpContext.Current?.Response;
            var contextItems = HttpContext.Current?.Items;

            Task.Run(async () =>
            {
                var taskContext = new HttpContext(httpRequest, httpResponse);

                if (contextItems?.Keys != null)
                {
                    foreach (var key in contextItems.Keys)
                    {
                        taskContext.Items.Add(key, contextItems[key]);
                    }
                }

                HttpContext.Current = taskContext; // Context gets copied here correctly.

                try
                {
                    await this.Secondary.InsertAsync(item);
                }
                catch (Exception ex)
                {
                    // Log error
                }
            });
        }
 public virtual async Task InsertAsync(TModel item)
        {

            var contextBeforeAwait = HttpContext.Current;  // This is not null
            await this.DoAsyncWork();
            var contextAfterAwait = HttpContext.Current; // Context here becomes null
            
           // Remaining Upsert logic which needs to use HttpContext.Current
        }

Web.config 有:

 <httpRuntime maxQueryStringLength="32768" maxUrlLength="65536" targetFramework="4.5" requestValidationMode="2.0" requestPathInvalidCharacters="&lt;,&gt;,*,&amp;,\,?" />

 <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

请让我知道如何避免此问题并在 Task.Run 中的 async/await 调用后保留 HttpContext

c# asp.net .net asynchronous async-await
1个回答
0
投票

我想使用 Task.Run 以“即发即忘”的方式执行 C# 中的方法。

您确定这就是您想要的吗?我只是问,因为在 >90% 的情况下,人们认为他们想要一劳永逸,这实际上是他们用例的错误解决方案。

具体来说,即发即弃意味着“我不在乎此代码有时是否不运行,并且我没有收到任何有关它不运行的日志或任何类型的通知。”对于更新缓存之类的事情来说还可以,但对于更新数据库记录之类的事情来说真的很糟糕。

在Task.Run中,每当我使用await执行另一个异步方法时,HttpContext就会变为null。请告诉我是否有办法在 Task.Run 中运行异步方法时保留 HttpContext

不,没有。事实上,您根本不应该从另一个线程访问任何

HttpContext
属性或方法。换句话说,Task.Run内的
no
代码应该完全访问
HttpContext
。事实上,它的一部分起作用纯粹是偶然的(如果时间不同,它可能会在生产运行时失败)。

更正确的解决方案是先从

HttpContext

 中复制所需的所有内容,然后 
然后 启动后台工作,传入该数据副本。

© www.soinside.com 2019 - 2024. All rights reserved.