简体   繁体   English

我如何让后台工作人员在 asp.net 核心中每 5 分钟更新一次数据存储

[英]how do i make a background worker to update a datastore every 5 minutes in asp.net core

I've followed the getting started tutorial and currently have a TODO CRUD app.我遵循了入门教程,目前有一个 TODO CRUD 应用程序。

https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api-mac?view=aspnetcore-2.1 https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api-mac?view=aspnetcore-2.1

I want to add a background worker that updates the todo database every 5 minutes and sets Item 1 to a random value for its Name, and isCompleted properties.我想添加一个后台工作程序,每 5 分钟更新一次待办事项数据库,并将项目 1 设置为其 Name 和 isCompleted 属性的随机值。

This is pretty easy in Java SpringBoot or Elixir's Phoenix... Is there a quick and painless way in c# to do this?这在 Java SpringBoot 或 Elixir's Phoenix 中非常简单......在 c# 中是否有一种快速而轻松的方法来做到这一点?

The doc I found on Microsoft website was from 2012... so I assume there is a more elegant way to do this by now.我在 Microsoft 网站上找到的文档是 2012 年的……所以我认为现在有一种更优雅的方法可以做到这一点。

Edit: I went with DNTScheduler.Core and it was relatively painless to set up.编辑:我使用了 DNTScheduler.Core,设置起来相对轻松。 Followed the exampleApp setup that was on github repo and here is the task i ended up using:按照github repo上的exampleApp设置,这是我最终使用的任务:

using System;
using System.Threading.Tasks;
using DNTScheduler.Core.Contracts;
using Microsoft.Extensions.Logging;
using myapp.Models;

namespace MyApp.Tasks
{
    public class TaskOne : IScheduledTask
    {
        private readonly ILogger<DoBackupTask> _logger;
        private readonly TodoContext _context; // autoinjects since it was added in startup.cs in configure()

        public TaskOne(ILogger<DoBackupTask> logger, TodoContext context)
        {
            _logger = logger;
            _context = context;
        }

        public Task RunAsync()
        {

            var todo = _context.TodoItems.Find(1);
            if (todo == null)
            {
                return Task.CompletedTask;
            }

            string[] names = new string[] { "val1", "val2"};
            Random r = new Random();
            string random_name = names[r.Next(0, names.Length)];
            todo.Name = random_name;

            _context.TodoItems.Update(todo);
            _context.SaveChanges();
            _logger.LogInformation("Ran My Task\n\n ");

            return Task.CompletedTask;

        }
    }
}

I would suggest you use Scheduler, there are some packages that can do that, but the best package that I have seen so far is DNTScheduler.Core我建议你使用 Scheduler,有一些包可以做到这一点,但到目前为止我见过的最好的包是DNTScheduler.Core

DNTScheduler.Core is a lightweight ASP.NET Core's background tasks runner and scheduler. DNTScheduler.Core是一个轻量级的 ASP.NET Core 后台任务运行器和调度器。

for more information, you can visit this link有关更多信息,您可以访问此链接

I would argue that the correct answer is wrong if you want to follow the native practice.如果您想遵循本地实践,我会争辩说正确的答案是错误的。

Make use of IHostedService to perform repetitive actions.利用 IHostedService 执行重复操作。

Here's an answer I've written that addresses that.这是我写的一个解决这个问题的答案

There is a saying i've read somewhere: "If its worth doing, its worth doing right. If its not worth doing right - find something that is."我在某处读到过一句话:“如果值得做,就值得做正确的事情。如果不值得做正确的事情——找点事情做。”

So, as other colleagues already said, web application is not meant to be a container for background processes for reasons already mentioned.因此,正如其他同事已经说过的,由于已经提到的原因,Web 应用程序并不意味着成为后台进程的容器。

Depending on your environment, you'll be much better off using:根据您的环境,您最好使用:

  1. windows services or even windows scheduler (on classic hosting) or some of the libraries for scheduling but outside of the web app. windows 服务甚至 windows 调度程序(在经典主机上)或一些用于调度但在 Web 应用程序之外的库。 then, those scheduler, whichever it is, could just trigger API endpoint within your web app so you have business logic at one place然后,那些调度程序,无论是哪一个,都可以在您的 Web 应用程序中触发 API 端点,以便您在一个地方拥有业务逻辑
  2. azure scheduler if you work with azure如果您使用 azure,请使用 azure 调度程序

pretty much anything else is looking for trouble when you don't need one.当您不需要任何其他东西时,几乎所有其他东西都在寻找麻烦。

In this sample I Insert a record to my database ( Word-Suggestion-Table in here) every hour using UnitOfWork and Repository Pattern .在这个示例中,我每小时使用UnitOfWorkRepository Pattern向我的数据库(此处为 Word-Suggestion-Table)插入一条记录。 No error on Cannot consume scoped service *IUnitOfWork* from singleton Cannot consume scoped service *IUnitOfWork* from singleton上没有错误

1- Add work class and IWork interface as below: 1- 添加work类和IWork接口如下:

using System.Threading;
using System.Threading.Tasks;

namespace Map118.App.BackgroundTasks
{
    public interface IWorker
    {
        Task DoWork(CancellationToken cancellationToken);
    }
}

Work.cs :工作.cs:

using Map118.DataLayer.IRepositories;
using Map118.Models;
using Microsoft.Extensions.DependencyInjection; 
using System; 
using System.Threading;
using System.Threading.Tasks;

namespace Map118.App.BackgroundTasks
{
    public class Worker : IWorker
    {            
        private readonly IServiceProvider serviceProvider;
        public Worker( IServiceProvider serviceProvider)
        {               
            this.serviceProvider = serviceProvider;
        }

        public async Task DoWork(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                using (var scope = serviceProvider.CreateScope())
                {
                    var _unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
                    while (!stoppingToken.IsCancellationRequested)
                    {
                        WordSuggestion wordSuggestion = new WordSuggestion()
                        {
                            word = Guid.NewGuid().ToString(),
                        };
                        await _unitOfWork.wordSuggestionRepository.Add(wordSuggestion);
                        await _unitOfWork.Save();
                        await Task.Delay(1000 * 3600);
                    }
                }
            }
        }
    }
}

2- Add another class as below: 2- 添加另一个类,如下所示:

using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;

namespace Map118.App.BackgroundTasks
{
    public class UserActivitiesCleaner : BackgroundService
    {
        private readonly IWorker worker;

        public UserActivitiesCleaner(IWorker worker)
        {
            this.worker = worker;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            await worker.DoWork(stoppingToken);            
        }
    }
}

3- Add services to Startup.cs : 3- 向Startup.cs添加services

services.AddHostedService<UserActivitiesCleaner>();
services.AddSingleton<IWorker, Worker>();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何更新 Asp.net 核心中的用户声明 - How do I update user claims in Asp.net Core ASP.NET:如何每隔几分钟从Web服务器获取数据 - ASP.NET : How do I fetch data from a webserver every few minutes 如何使运行在Azure实例中的ASP.NET WebAPI程序每分钟更新一次数据库? - How can I make an ASP.NET WebAPI program running in an Azure instance update a database every minute? 如何正确处理 ASP.net Core 3 中的大型后台任务? - How do I properly handle a large background task in ASP.net Core 3? 如何创建在每个给定时间段运行一个函数的 BackGround 服务? 使用 C#(asp.net 核心 3.1.1) - How can I create a BackGround service that runs a function every given period of time ? Using C# (asp.net core 3.1.1) 如何从asp.net核心视图更新javascript中的模型值 - How do I update model value in javascript from asp.net core view 如何在我的 ASP.NET Core 应用程序中显示和更新我的自定义标识字段? - How do I display and update my custom Identity fields in my ASP.NET Core application? 使用 ASP.NET Core 3,如何使 json 响应不序列化复杂类型? - Using ASP.NET Core 3, how do I make the json response not serialize a complex type? 如何使 ASP.NET Core 无效/任务操作方法返回 204 No Content - How do I make an ASP.NET Core void/Task action method return 204 No Content ASP.Net Core 3:如何使 @Html.DropDownListFor 具有默认值的“只读”? - ASP.Net Core 3: How do I make an @Html.DropDownListFor “read-only” with a default value?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM