前面幾篇都是用 SQL Server,這篇就試試 SQLite 吧
開發環境
- VS 2019
- .NET Framework 4.8
- Console App Template Project
管理工具
DB Browser for SQLite
管理的工具只是用來確定 Code First 產生的資料結構如預期,我採用 DB Browser for SQLite,下載位置如下
開始實作
安裝套件
Install-Package System.Data.SQLite
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
Install-Package Microsoft.Owin.Diagnostics
Install-Package Microsoft.Owin.Host.SystemWeb
Install-Package Hangfire
Install-Package Hangfire.MemoryStorage
Install-Package Hangfire.Sqlite
Install-Package Hangfire.Console
Install-Package Hangfire.Dashboard.Management
組態設定
<connectionStrings>
<add name="Hangfire" connectionString="data source=hangfire.db" providerName="System.Data.SQLite" />
</connectionStrings>
HangfireConfig
- 使用 SQLite 的連線字串名稱
- 設定 Hangfore URL
internal class HangfireConfig
{
private static readonly string DbConnectionName = "Hangfire";
private static readonly string Url = "/hangfire";
public static void Register(IAppBuilder app)
{
GlobalConfiguration.Configuration
.UseDashboardMetric(DashboardMetrics.ServerCount)
.UseDashboardMetric(DashboardMetrics.RecurringJobCount)
.UseDashboardMetric(DashboardMetrics.RetriesCount)
.UseDashboardMetric(DashboardMetrics.EnqueuedCountOrNull)
.UseDashboardMetric(DashboardMetrics.FailedCountOrNull)
.UseDashboardMetric(DashboardMetrics.EnqueuedAndQueueCount)
.UseDashboardMetric(DashboardMetrics.ScheduledCount)
.UseDashboardMetric(DashboardMetrics.ProcessingCount)
.UseDashboardMetric(DashboardMetrics.SucceededCount)
.UseDashboardMetric(DashboardMetrics.FailedCount)
.UseDashboardMetric(DashboardMetrics.DeletedCount)
.UseDashboardMetric(DashboardMetrics.AwaitingCount)
.UseManagementPages(cc => cc.AddJobs(() => { return GetModuleTypes(); }))
.UseSQLiteStorage(DbConnectionName)
.UseConsole()
;
var options = new BackgroundJobServerOptions
{
ServerName = $"{Environment.MachineName}.{Guid.NewGuid().ToString()}",
WorkerCount = 20,
Queues = new[] {"critical", "normal", "low"}
};
var dashboardOptions = new DashboardOptions
{
Authorization = new IDashboardAuthorizationFilter[] {new DashboardAuthorizationFilter()}
};
app.UseHangfireDashboard(Url, dashboardOptions);
app.UseHangfireServer(options);
}
private static Type[] GetModuleTypes()
{
var assemblies = new[] {Assembly.GetEntryAssembly()};
var moduleTypes = assemblies.SelectMany(f =>
{
try
{
return f.GetTypes();
}
catch (Exception)
{
return new Type[] { };
}
}
) /*.Where(f => f.IsClass && typeof(IClientModule).IsAssignableFrom(f))*/
.ToArray();
return moduleTypes;
}
}
DemoJob
[ManagementPage("演示", "low")]
public class DemoJob
{
[Hangfire.Dashboard.Management.Support.Job]
[DisplayName("呼叫內部方法")]
[Description("呼叫內部方法")]
[AutomaticRetry(Attempts = 3)] //自動重試
[DisableConcurrentExecution(90)] //禁止使用並行
public void Action(PerformContext context = null, IJobCancellationToken cancellationToken = null)
{
if (cancellationToken.ShutdownToken.IsCancellationRequested)
{
return;
}
context.WriteLine($"測試用,Now:{DateTime.Now}");
//Thread.Sleep(30000);
}
}
Startup
public class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
var config = new HttpConfiguration();
config.Filters.Add(new ErrorHandlerAttribute());
HangfireConfig.Register(app);
config.Routes.MapHttpRoute("DefaultApi",
"api/{controller}/{id}",
new {id = RouteParameter.Optional}
);
app.UseWelcomePage("/");
app.UseWebApi(config);
app.UseErrorPage();
}
}
掛載服務
internal class Program
{
private const string HOST_ADDRESS = "http://localhost:9527";
private static IDisposable s_webApp;
private static void Main(string[] args)
{
s_webApp = WebApp.Start<Startup>(HOST_ADDRESS);
Console.WriteLine("Hangfire service start...");
Console.ReadLine();
}
}
調試服務
Ctrl + F5,用瀏覽器訪問 http://localhost:9527/hangfire
https://dotblogs.com.tw/yc421206/2020/01/30/via_nancy_create_rest_api#%E7%B6%81%E5%AE%9A%20URL
範例位置
https://github.com/yaochangyu/sample.dotblog/tree/master/Hangfire/Lab.HangfireSqliteStorage
延伸閱讀
[Hangfire] 使用 Hangfire OWIN 建立非同步任務
[Hangfire] ASP.NET Core Hangfire 排程管理 - Hangfire.Dashboard.Management
[EF6][SQLite] SQLite Code First 和 Migration
後記
發現 Hangfire.SQLite 有 Bug,當 WorkCount 有 20 個,工作就會執行 20 次,作者建議把 WorkCount 設為 1, https://github.com/wanlitao/HangfireExtension/issues/3,因為它已經很久沒有更新了,我已經改用 Hangfire.Storage.SQLite。使用方式跟 Hangfire.SQLite 差不多,差異在於連線字串的處理,它似乎沒有支援讀取 web.config/app.config 的功能,這可以自己處理不是甚麼大問題。
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET