.NET Core 中 HostingEnvironment.QueueBackgroundWorkItem 的替代解决方案

编程入门 行业动态 更新时间:2024-10-28 13:14:15
本文介绍了.NET Core 中 HostingEnvironment.QueueBackgroundWorkItem 的替代解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我们正在使用 .NET Core Web Api,并寻找一种轻量级的解决方案来将可变强度的请求记录到数据库中,但不希望客户端等待保存过程.不幸的是,在 dnx 中没有实现 HostingEnvironment.QueueBackgroundWorkItem(..),并且 Task.Run(..) 并不安全.有什么优雅的解决方案吗?

We are working with .NET Core Web Api, and looking for a lightweight solution to log requests with variable intensity into database, but don't want client's to wait for the saving process. Unfortunately there's no HostingEnvironment.QueueBackgroundWorkItem(..) implemented in dnx, and Task.Run(..) is not safe. Is there any elegant solution?

推荐答案

QueueBackgroundWorkItem 不见了,但我们得到的是 IApplicationLifetime 而不是 IRegisteredObject,这是前一个正在使用的.我认为,在这种情况下,它看起来很有希望.

QueueBackgroundWorkItem is gone, but we've got IApplicationLifetime instead of IRegisteredObject, which is being used by the former one. And it looks quite promising for such scenarios, I think.

这个想法(我仍然不太确定,如果它是一个非常糟糕的一个;因此,当心!)是注册一个单例,它产生 并 观察新任务.在该单例中,我们还可以注册一个停止事件",以便正确等待仍在运行的任务.

The idea (and I'm still not quite sure, if it's a pretty bad one; thus, beware!) is to register a singleton, which spawns and observes new tasks. Within that singleton we can furthermore register a "stopped event" in order to proper await still running tasks.

这个概念"可用于短期运行的东西,如日志记录、邮件发送等.事情,应该不会花费太多时间,但会对当前请求产生不必要的延迟.

This "concept" could be used for short running stuff like logging, mail sending, and the like. Things, that should not take much time, but would produce unnecessary delays for the current request.

public class BackgroundPool { protected ILogger<BackgroundPool> Logger { get; } public BackgroundPool(ILogger<BackgroundPool> logger, IApplicationLifetime lifetime) { if (logger == null) throw new ArgumentNullException(nameof(logger)); if (lifetime == null) throw new ArgumentNullException(nameof(lifetime)); lifetime.ApplicationStopped.Register(() => { lock (currentTasksLock) { Task.WaitAll(currentTasks.ToArray()); } logger.LogInformation(BackgroundEvents.Close, "Background pool closed."); }); Logger = logger; } private readonly object currentTasksLock = new object(); private readonly List<Task> currentTasks = new List<Task>(); public void SendStuff(Stuff whatever) { var task = Task.Run(async () => { Logger.LogInformation(BackgroundEvents.Send, "Sending stuff..."); try { // do THE stuff Logger.LogInformation(BackgroundEvents.SendDone, "Send stuff returns."); } catch (Exception ex) { Logger.LogError(BackgroundEvents.SendFail, ex, "Send stuff failed."); } }); lock (currentTasksLock) { currentTasks.Add(task); currentTasks.RemoveAll(t => t.IsCompleted); } } }

这样的 BackgroundPool 应该注册为单例,并且可以通过 DI 被任何其他组件使用.我目前正在使用它来发送邮件,它工作正常(在应用关闭期间也测试过邮件发送).

Such a BackgroundPool should be registered as a singleton and can be used by any other component via DI. I'm currently using it for sending mails and it works fine (tested mail sending during app shutdown too).

注意: 在后台任务中访问诸如当前 HttpContext 之类的东西应该不起作用.旧解决方案 使用 UnsafeQueueUserWorkItem无论如何都要禁止.

Note: accessing stuff like the current HttpContext within the background task should not work. The old solution uses UnsafeQueueUserWorkItem to prohibit that anyway.

你怎么看?

更新:

有了 ASP.NET Core 2.0,后台任务有了新的东西,ASP.NET Core 2.1 变得更好:使用 IHostedService 和 BackgroundService 类在 .NET Core 2.x webapps 或微服务中实现后台任务

With ASP.NET Core 2.0 there's new stuff for background tasks, which get's better with ASP.NET Core 2.1: Implementing background tasks in .NET Core 2.x webapps or microservices with IHostedService and the BackgroundService class

更多推荐

.NET Core 中 HostingEnvironment.QueueBackgroundWorkItem 的替代解决方案

本文发布于:2023-11-14 02:06:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1585933.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:解决方案   Core   NET   QueueBackgroundWorkItem   HostingEnvironment

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!