C# 相当于asp.net框架中的Ihostedservice,用于后台任务
我在.NET4.6.2中有一个RESTfulMicro服务(WebAPI),我想在每次调用某些端点以执行一些数据库清理工作后调用fire-and-forget函数。我不想使用Task.Run,我希望有一个非常可靠的专用流程来完成这项工作 我发现了很多关于如何在.NETCore中使用IhostedService进行长时间运行的后台任务的文章和讨论 然而,我在.NETFramework中没有找到太多关于等价物的信息。那是我的注册对象吗?有人能帮我吗?或者告诉我正确的资源 注意:我们将API作为windows服务托管,不使用IISC# 相当于asp.net框架中的Ihostedservice,用于后台任务,c#,multithreading,rest,windows-services,microservices,C#,Multithreading,Rest,Windows Services,Microservices,我在.NET4.6.2中有一个RESTfulMicro服务(WebAPI),我想在每次调用某些端点以执行一些数据库清理工作后调用fire-and-forget函数。我不想使用Task.Run,我希望有一个非常可靠的专用流程来完成这项工作 我发现了很多关于如何在.NETCore中使用IhostedService进行长时间运行的后台任务的文章和讨论 然而,我在.NETFramework中没有找到太多关于等价物的信息。那是我的注册对象吗?有人能帮我吗?或者告诉我正确的资源 注意:我们将API作为
这是我第一次在这里提问,因此,如果问题不够明确,我深表歉意。最安全的方法之一是使用线程。 你可以启动线程,让它运行 如果在应用程序关闭时需要终止线程,可以添加isBackground参数。
否则,线程应继续运行,直到其工作完成
threadbackgroundthread=新线程(()=>
{
WriteLine(“我将一直运行,直到应用程序停止或我完成工作”);
LongRunningJob();
},IsBackground=true);
线程foregroundThread=新线程(()=>
{
Console.WriteLine(“完成后我会停止”);
LongRunningJob();
}
backgroundThread.Start();
foregroundThread.Start()
我想这有点太晚了,但对于有同样问题的人来说
你知道吗
也许这两者中的一个在你的情况下都是非常有用的工具。
我在许多应用程序中使用过它,从来没有出现过任何问题
例如,在Quartz.Net中,首先必须通过创建实现IJob接口的类来创建“作业”(这是用于此类后台服务的术语):
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync("Greetings from HelloJob!");
}
}
然后,您必须定义何时要检查该作业,有很多方法(例如CRON),但我们这里只使用一个简单的时间表:
StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
await scheduler.Start();
// define the job
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build();
// Trigger the job to run now, and then repeat every 20 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(20)
.RepeatForever())
.Build();
// Tell quartz to schedule the job using our trigger, DON'T FORGET THIS ONE
await scheduler.ScheduleJob(job, trigger);
我个人非常喜欢这种方法。它是可重用的(你只需要在这里安排一个新的工作),并且对于你团队中的任何开发人员来说都很容易进入
我希望它能对您的问题有所帮助。ASP.NET有一个运行后台任务的本机解决方案:
HostingEnvironment.QueueBackgroundWorkItem
方法,可在System.Web.Hosting
上找到
它适用于同步或async
方法。与使用ThreadPool
不同,QueueBackgroundWorkItem
确保ASP.NET运行时在有任何挂起的工作项运行时延迟应用程序关闭
从:
与普通线程池工作项的不同之处在于,ASP.NET可以跟踪通过此API注册的工作项当前正在运行的数量,并且ASP.NET运行时将尝试延迟AppDomain关闭,直到这些工作项完成执行。无法在ASP.NET托管的AppDomain之外调用此API。提供的取消操作将在ionToken将在应用程序关闭时发出信号
下面是一个如何使用它的示例:
使用系统;
使用系统诊断;
使用系统线程;
使用System.Threading.Tasks;
使用System.Web.Hosting;
使用System.Web.Http;
命名空间BackgroundWorkItemExample.Controllers
{
公共类HomeController:ApiController
{
[HttpPost]
公共IHttpActionResult执行()
{
Debug.WriteLine(“做某事”);
HostingEnvironment.QueueBackgroundWorkItem(ct=>FireAndForgetMethodAsync());
HostingEnvironment.QueueBackgroundWorkItem(ct=>FireAndForgetMethod());
HostingEnvironment.QueueBackgroundWorkItem(ct=>FaultyFireAndForgetMethod());
WriteLine(“我不喜欢那些在后台运行的东西,我退出了。”);
return Ok(“无论异常情况如何,它仍然返回。”);
}
专用异步任务FireAndForgetMethodAsync()
{
WriteLine(“开始运行异步后台工作项…”);
等待任务。延迟(5000);//假装我们正在做某事5秒钟
Debug.WriteLine(“完成运行该命令”);
}
私有无效FireAndForgetMethod()
{
WriteLine(“已开始运行后台工作项…”);
Thread.Sleep(5000);//假装我们在做什么
Debug.WriteLine(“完成运行该命令”);
}
私有void FaultyFireAndForgetMethod()
{
抛出新的异常(“我失败只是为了说明问题。”);
}
}
}
产出将是:
做某事。
我不喜欢那些在后台运行的东西,我出去了。
已开始运行后台工作项。。。
已开始运行异步后台工作项。。。
引发异常:WebApplication1.dll中的“System.Exception”
WebApplication1.dll中发生“System.exception”类型的异常,但未在用户代码中处理
我失败只是为了说明一点。
我已经跑完了。
我已经跑完了。
您找到解决此问题的方法了吗?没有。我们向数据库队列插入了一条记录,并使用windows服务来处理该记录并进行工作。这是一个完美的使用案例。这可以在IIS或windows服务中运行。如果您使用的是微服务方法,则在微服务之后将其拆分为单独的进程e架构(我的看法)。将消息发布到消息总线,并拥有一个处理消息的服务。将其添加到现有API中会让人感觉到微服务少了很多,而monolith IMO则多了一些。在我们的应用程序中,我们有很多后台任务。这些任务应该在用户执行某些操作时开始:创建记录、更新记录等。此工具对我们帮助很大。是的,我我会建议你用那把枪和它的
await scheduler.Shutdown();