国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - Asp.net core Webapi 如何執行定時任務?

Asp.net core Webapi 如何執行定時任務?

2024-01-06 00:03未知服務器之家 ASP.NET教程

Asp.net core Webapi 有沒有辦法執行定時任務呢?答案是有的 前言 在計算機系統中,定時執行一些后臺任務是很常見的場景,比如定時發送郵件、備份數據等等。 那么,.NET 技術如何通過編程靈活地實現項目里復雜的自定義任務呢?

Asp.net core Webapi 有沒有辦法執行定時任務呢?答案是有的

Asp.net core Webapi 如何執行定時任務?

前言

在計算機系統中,定時執行一些后臺任務是很常見的場景,比如定時發送郵件、備份數據等等。

那么,.NET 技術如何通過編程靈活地實現項目里復雜的自定義任務呢?

如果是 Windows 生態,通常來說,可以有這些方式:

  1. 編寫一個程序,通過 Windows 內置的任務計劃來定時執行。
  2. 編寫一個程序,通過 Windows 內置的 Services 來定時執行。
  3. 編寫一個定時循環執行任務的程序,在 Windows 系統啟動時配置為自動執行。
    ……

但是,如果是一個中小型的 Web 應用系統,這些方法方式就顯得不太合適。Asp.net core Webapi 有沒有辦法執行定時任務呢?答案是有的,Asp.net core Webapi 可以通過常駐后臺的托管服務來執行定時任務。

本文是 Asp.net core Webapi 運行一個常駐后臺并從數據庫中導出數據的托管服務的例子,寫出來供大家指點,在討論過程*同提高水平。

Step By Step 實現步驟

  1. 創建一個 asp.net core webapi 項目
  2. 從 Nuget 安裝以下包

    Microsoft.AspNetCore.Identity.EntityFrameworkCore
    Microsoft.EntityFrameworkCore.Relational
    Microsoft.EntityFrameworkCore.SqlServer
    Microsoft.EntityFrameworkCore.Tools

  3. 打開 appsettings.json 并添加數據庫連接字符串,如:
    {
      "Logging": {
    	"LogLevel": {
    	  "Default": "Information",
    	  "Microsoft.AspNetCore": "Warning"
    	}
      },
      "AllowedHosts": "*",
      "ConnectionStrings": {
    	"Default": "Server=(localdb)\\mssqllocaldb;Database=IdentityTestDB;Trusted_Connection=True;MultipleActiveResultSets=true"
      }
    }
    
  4. 添加一個繼承于 IdentityUser 的 User 類
    using Microsoft.AspNetCore.Identity;
    
    public class User: IdentityUser<long>
    {
    	public DateTime CreationTime { get; set; }
    	public string? NickName { get; set; }
    }	
    
  5. 添加一個繼承于 IdentityRole 的 Role 類
    using Microsoft.AspNetCore.Identity;
    
    public class Role: IdentityRole<long>
    {
    
    }
    
  6. 創建數據庫上下文
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore;
    
    public class TestDbContext: IdentityDbContext<User, Role, long>
    {
    	public TestDbContext(DbContextOptions<TestDbContext> options):base(options)
    	{
    
    	}
    
    	protected override void OnModelCreating(ModelBuilder builder)
    	{
    		base.OnModelCreating(builder);
    		builder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
    	}
    }	
    
  7. 創建一個 ExplortStatisticBgService 類并繼承 BackgroundService,這是托管服務類
    using Microsoft.EntityFrameworkCore;
    using System.Text;
    
    public class ExplortStatisticBgService : BackgroundService
    {
    	private readonly TestDbContext ctx;
    	private readonly ILogger<ExplortStatisticBgService> logger;
    	private readonly IServiceScope serviceScope;
    
    	/// <summary>
    	/// 在構造方法注入IServiceScopeFactory服務,
    	/// 用來創建IServiceScope對象,
    	/// 這樣就可以通過IServiceScope來創建短生命周期的服務了
    	/// </summary>
    	/// <param name="scopeFactory"></param>
    	public ExplortStatisticBgService(IServiceScopeFactory scopeFactory)
    	{
    		this.serviceScope = scopeFactory.CreateScope();
    		var sp = serviceScope.ServiceProvider;
    		this.ctx = sp.GetRequiredService<TestDbContext>();
    		this.logger = sp.GetRequiredService<ILogger<ExplortStatisticBgService>>();  
    	}
    
    	protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    	{
    		// 用 while 循環實現服務常駐
    		while (!stoppingToken.IsCancellationRequested)
    		{
    			// 用 try...catch 捕捉異常記錄錯誤信息并避免方法退出
    			try
    			{
    				// 這里實現每隔5秒從數據庫中導出數據
    				// 更復雜的配置可以用第三方開源的框架
    				await DoExecuteAsync();
    				await Task.Delay(5000);
    			}
    			catch (Exception ex)
    			{
    				logger.LogError(ex, "獲取用戶統計數據失敗");
    				await Task.Delay(1000);
    			}
    		}
    	}
    
    	private async Task DoExecuteAsync()
    	{
    		var items = ctx.Users.AsNoTracking().GroupBy(u => u.CreationTime.Date)
    			.Select(e => new 
    			{ 
    				Date = e.Key,
    				Count = e.Count()
    			});
    		StringBuilder sb = new StringBuilder(1024);
    		sb.AppendLine($"Date: {DateTime.Now}");
    		foreach (var item in items)
    		{
    			sb.Append(item.Date).AppendLine($": {item.Count}");
    		}
    		await File.WriteAllTextAsync("d:/1.txt", sb.ToString());
    		logger.LogInformation($"導出完成");
    	}
    
    	/// <summary>
    	/// IServiceScope 需要釋放
    	/// 所以重寫 Dispose 方法
    	/// </summary>
    	public override void Dispose()
    	{
    		base.Dispose();
    		serviceScope.Dispose();
    	}
    }	
    
  8. 打開 Program.cs,注入托管服務等,看代碼的注釋
    using Microsoft.AspNetCore.Identity;
    using Microsoft.EntityFrameworkCore;
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    
    builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    
    IServiceCollection services = builder.Services;
    
    // 注冊托管服務
    services.AddHostedService<ExplortStatisticBgService>();
    
    // 注入數據庫上下文
    services.AddDbContext<TestDbContext>(options => {
    	string connStr = builder.Configuration.GetConnectionString("Default")!;
    	options.UseSqlServer(connStr);
    });
    
    // 數據保護服務注入
    // ----數據保護提供了一個簡單、基于非對稱加密改進的加密API用于確保Web應用敏感數據的安全存儲
    // ----不需要開發人員自行生成密鑰,它會根據當前應用的運行環境,生成該應用獨有的一個私鑰
    services.AddDataProtection();
    
    // 注入 Identity 框架的一些重要的基礎配置
    // 如果沒有這個,下面的注入 UserManager 等服務會有問題,程序無法編譯
    services.AddIdentityCore<User>(options =>
    {
    	options.Password.RequireDigit = false;
    	options.Password.RequireLowercase = false;
    	options.Password.RequireNonAlphanumeric = false;
    	options.Password.RequireUppercase = false;
    	options.Password.RequiredLength = 6;
    	options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
    	options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
    });
    
    // 注入 UserManager、RoleManager 等Identity 框架服務
    var idBuilder = new IdentityBuilder(typeof(User), typeof(Role), services);
    idBuilder.AddEntityFrameworkStores<TestDbContext>()
    	.AddDefaultTokenProviders()
    	.AddRoleManager<RoleManager<Role>>()
    	.AddUserManager<UserManager<User>>();
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
    	app.UseSwagger();
    	app.UseSwaggerUI();
    }
    
    app.UseHttpsRedirection();
    
    app.UseAuthorization();
    
    app.MapControllers();
    
    app.Run();
    ``
    
  9. Ctrl+F5 運行項目,不做任何操作,托管程序會自動導出數據

擴展

托管服務在后臺運行,通過它可以實現在很多事情,比如:

  1. 監控消息隊列,當有數據進入消息隊列就處理。
  2. 再如每隔10s把A數據庫中的數據同步到B數據庫中
  3. ...... 等等

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本在线一区二区 | 久久久精 | 久久这里有精品视频 | 国产欧美日韩在线 | 国产精品久久久久一区二区三区 | 中文字幕高清视频 | 精品国产一区二区在线 | 国产一级一级国产 | 亚洲国产精品久久 | 国产色 | 久久白虎 | 7799精品视频天天看 | 日韩影片在线观看 | 亚洲综合色自拍一区 | 台湾黄色网 | 精品一区二区三区在线观看 | 久久网站热最新地址 | 国产免费看 | 伊人色私人影院蜜桃va | 一本久久a久久精品亚洲 | 日本不卡一区二区三区在线观看 | 免费污污视频在线观看 | 黄色大片网 | 亚洲欧洲精品视频在线观看 | 国产 一区 | 亚洲一区自拍偷拍 | 欧美日韩高清不卡 | 黄色片网站 | 免费观看的黄色 | 日韩欧美国产一区二区三区 | 激情一区二区 | 久久99精品久久久久久久青青日本 | 国产在线观看一区 | 羞羞的视频 | 亚洲精彩视频在线 | 欧美成人午夜视频 | 激情五月综合网 | 亚洲欧美日韩另类精品一区二区三区 | 国产婷婷在线观看 | 色www精品视频在线观看 | 色婷婷在线视频观看 |