【问题标题】:Hangfire single instance recurring jobHangfire 单实例重复作业
【发布时间】:2015-08-27 13:11:26
【问题描述】:

我正在尝试使用 Hangfire 在后台运行一个循环作业,该作业从另一个网站轮询数据,问题是如果前一个作业仍在运行,我不希望循环作业运行。

我已通读文档,但似乎找不到答案。有没有办法让重复作业每 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);
}

【问题讨论】:

  • 这里有一个建议:只需将作业作为单个实例进行排队。然后,如果作业成功完成,您将执行作业的最后一步。作业的最后一步将在 10 分钟后将作业排入队列以再次执行。这不会为您提供所需的功能吗?
  • 你的意思是同一个循环任务的最后一次执行吗?

标签: c# asp.net-mvc hangfire


【解决方案1】:

你可以使用; 作业方法上的[DisableConcurrentExecution(10 * 60)] 属性。

您可以在此处找到有关此属性的信息: http://odinserj.net/2014/05/21/hangfire-0.8.2-released/

【讨论】:

    【解决方案2】:

    我的解决方案:

    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
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2022-11-15
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      • 2013-11-05
      • 2016-11-11
      • 2019-01-08
      • 2019-10-29
      • 2020-01-11
      相关资源
      最近更新 更多