如何在Task.Run中使用HttpContext?

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

在中间件中记录RequestResponse,当在Task.Run()中使用'await'时,它可以工作,但由于它在等待当前操作完成,因此存在性能问题。

当我把 await 移除后,运行速度很快,但没有任何记录,因为HttpContext实例在并行线程中无法使用。

public class LoggingHandlerMiddleware
    {
        private readonly RequestDelegate next;
        private readonly ILoggerManager _loggerManager;

        public LoggingHandlerMiddleware(RequestDelegate next, ILoggerManager loggerManager)
        {
            this.next = next;
            _loggerManager = loggerManager;
        }

        public async Task Invoke(HttpContext context, ILoggerManager loggerManager, IWebHostEnvironment environment)
        {
                _ = Task.Run(() =>
                  {
                      AdvanceLoggingAsync(context, _loggerManager, environment);
                  });
              ...
        }

        private void AdvanceLoggingAsync(HttpContext context, ILoggerManager loggerManager, IWebHostEnvironment environment, bool IsResponse = false)
            {
                 {
                    context.Request.EnableBuffering(); // Throws ExecutionContext.cs not found
                    result += $"ContentType:{context.Request.ContentType},";

                    using (StreamReader reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true))
                    {
                        result += $"Body:{await reader.ReadToEndAsync()}";
                        context.Request.Body.Position = 0;
                    }
                    loggerManager.LogInfo($"Advance Logging Content(Request)-> {result}");
            }

如何利用访问HttpContext的Task.Run()性能?

async-await task-parallel-library
1个回答
0
投票

好吧,你可以从上下文中提取你需要的东西,建立你想要记录的字符串,然后将该字符串传递给你运行的任务。

然而,发射和忘记一个任务是不好的。 如果它抛出一个异常,你就有可能使服务器瘫痪,或者至少你将很难得到有关错误的信息。

如果你关注日志性能,最好将你需要记录的内容添加到消息队列中,并有一个进程响应队列中的新消息并将消息记录到日志文件中。

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