Hangfire 单实例重复作业
Hangfire single instance recurring job
我正在尝试使用 Hangfire 运行 在后台轮询来自另一个网站的数据的循环作业,问题是我不希望循环作业 运行 如果之前的工作还在运行ning.
我通读了文档,但似乎找不到答案。有没有一种方法可以让 运行 每 10 分钟重复一次,但如果上一个任务尚未完成则跳过?
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
// Hangfire
GlobalConfiguration.Configuration
.UseSqlServerStorage("DatabaseContext");
app.UseHangfireDashboard();
app.UseHangfireServer();
RecurringJob.AddOrUpdate("site-parser", () => SiteParserService.RunAll(), Cron.Minutely, TimeZoneInfo.Utc);
ConfigureAuth(app);
}
可以使用;
[DisableConcurrentExecution(10 * 60)]
作业方法上的属性。
您可以在此处找到有关此属性的信息:
http://odinserj.net/2014/05/21/hangfire-0.8.2-released/
我的解决方案:
namespace MyNameSpace
{
public delegate void LockWrapperDelegateVoid();
/* Job Locker. One job can work at current moment. Different jobs can work parallel */
public static class JobLocker
{
private static readonly ConcurrentDictionary<string, bool> _locks = new ConcurrentDictionary<string, bool>();
private static string LocksTryAdd(string lockerName)
{
if (string.IsNullOrEmpty(lockerName)) // lock by procedure's name (in this example = "JobProcedure")
{
lockerName = new StackFrame(2).GetMethod().Name;
}
if (!_locks.ContainsKey(lockerName))
{
_locks.TryAdd(lockerName, false);
}
return lockerName;
}
public static void LockWrapperVoid(string lockerName, LockWrapperDelegateVoid lockWrapperDelegateVoid)
{
lockerName = LocksTryAdd(lockerName);
if (!_locks[lockerName])
{
_locks[lockerName] = true;
try
{
lockWrapperDelegateVoid();
}
finally
{
_locks[lockerName] = false;
}
}
}
}
}
// USING
// JOB description
TryAddOrUpdateJob("JOB TITLE", () => JobManager.JobProcedure(), "* * * * *", TimeZoneInfo.Utc, "queueDefault"); // every one minute
public static void JobProcedure()
{
// very important. You can use "BlockArea" instead null and use one area if several jobs depend each other
// if null - area will have name like as the procedure ("JobProcedure")
JobLocker.LockWrapperVoid(null, () =>
{
//your code here
System.Threading.Thread.Sleep(2 * 1000 * 60); // timeout - 2 minutes
});
}
我正在尝试使用 Hangfire 运行 在后台轮询来自另一个网站的数据的循环作业,问题是我不希望循环作业 运行 如果之前的工作还在运行ning.
我通读了文档,但似乎找不到答案。有没有一种方法可以让 运行 每 10 分钟重复一次,但如果上一个任务尚未完成则跳过?
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
// Hangfire
GlobalConfiguration.Configuration
.UseSqlServerStorage("DatabaseContext");
app.UseHangfireDashboard();
app.UseHangfireServer();
RecurringJob.AddOrUpdate("site-parser", () => SiteParserService.RunAll(), Cron.Minutely, TimeZoneInfo.Utc);
ConfigureAuth(app);
}
可以使用;
[DisableConcurrentExecution(10 * 60)]
作业方法上的属性。
您可以在此处找到有关此属性的信息: http://odinserj.net/2014/05/21/hangfire-0.8.2-released/
我的解决方案:
namespace MyNameSpace
{
public delegate void LockWrapperDelegateVoid();
/* Job Locker. One job can work at current moment. Different jobs can work parallel */
public static class JobLocker
{
private static readonly ConcurrentDictionary<string, bool> _locks = new ConcurrentDictionary<string, bool>();
private static string LocksTryAdd(string lockerName)
{
if (string.IsNullOrEmpty(lockerName)) // lock by procedure's name (in this example = "JobProcedure")
{
lockerName = new StackFrame(2).GetMethod().Name;
}
if (!_locks.ContainsKey(lockerName))
{
_locks.TryAdd(lockerName, false);
}
return lockerName;
}
public static void LockWrapperVoid(string lockerName, LockWrapperDelegateVoid lockWrapperDelegateVoid)
{
lockerName = LocksTryAdd(lockerName);
if (!_locks[lockerName])
{
_locks[lockerName] = true;
try
{
lockWrapperDelegateVoid();
}
finally
{
_locks[lockerName] = false;
}
}
}
}
}
// USING
// JOB description
TryAddOrUpdateJob("JOB TITLE", () => JobManager.JobProcedure(), "* * * * *", TimeZoneInfo.Utc, "queueDefault"); // every one minute
public static void JobProcedure()
{
// very important. You can use "BlockArea" instead null and use one area if several jobs depend each other
// if null - area will have name like as the procedure ("JobProcedure")
JobLocker.LockWrapperVoid(null, () =>
{
//your code here
System.Threading.Thread.Sleep(2 * 1000 * 60); // timeout - 2 minutes
});
}