考慮到使用外部排程器呼叫API方式執行文章同步,雖然可以切分功能,但總是不方便。這邊使用.net core自帶輕量級排程器 IHostedService + Timer 來實作定期更新文章功能。
【第一步】在設定檔跟其Model類別添加控制屬性:
1.UseITIronManLocalLoader的值為true開啟排程器功能,false關閉,預設關閉。
2.ITIronManLocalLoaderInterval決定排程器間隔時間,以小時為單位,預設24小時。
{
"blog": {
"UseITIronManLocalLoader": true,
"ITIronManLocalLoaderInterval" : 24
}
}
public class BlogSettings
{
public bool UseITIronManLocalLoader { get; set; } = false;
public int ITIronManLocalLoaderInterval { get; set; } = 24;/*預設24小時*/
}
【第二步】建立排程器類別,實作 IHostedService 介面,並註冊服務:
IHostedService需要實作兩個方法:StartAsync
、StopAsync
public interface IHostedService
{
Task StartAsync(CancellationToken cancellationToken);
Task StopAsync(CancellationToken cancellationToken);
}
接著在Startup.cs註冊Service:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedService<實作類別>();
}
}
範例:Miniblog.Core.W3C實作代碼
public class ITIronManSyncPostTimedHostedService : IHostedService, IDisposable
{
private Timer _timer;
public Task StartAsync(CancellationToken cancellationToken)
{
var time = TimeSpan.FromHours(Setting.sectionBlog.ITIronManLocalLoaderInterval);
_timer = new Timer(DoWork, null, time, time);
return Task.CompletedTask;
}
private void DoWork(object state)
{
if(ITIronManSyncPostService.SyncPostAsync().GetAwaiter().IsCompleted)
throw new Exception("Execute failed");
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
var section = Configuration.GetSection("blog").Get<BlogSettings>();
//是否要開啟IT鐵人賽自動文章同步排程器
if (section.UseITIronManLocalLoader)
services.AddHostedService<ITIronManSyncPostTimedHostedService>();
}
}
建議一天讀取兩次就好,避免造成IT邦的流量負擔,並且寫完所有文章後沒有更新需求,可以把排程器關閉。或是做其他應用都是大大們的自由,可以在源碼上自由修改。
最後再過幾小時終於可以終結這系列,專心寫Azure文章了!!
暐翰請問一下,這個方式可以用一般ConsoleApp來當作排程跑嗎? 我看原始文章寫得是ASP.NET Core的背景託管程式
Tony_Tsai 可以的,asp.net core本質上也是ConsoleApp