使用 Hangfire 创建重复作业时出错

Posted

技术标签:

【中文标题】使用 Hangfire 创建重复作业时出错【英文标题】:Error while creating recurring job using Hangfire 【发布时间】:2017-10-12 08:28:48 【问题描述】:

我正在尝试在我的应用程序中使用 Hangfire 来获取(从外部 API)每天的货币兑换率并插入应用程序数据库。 成功配置(这样想)并且在数据库中创建了 Hangfire 表,并且 Job 表有条目但 Job 没有成功执行,并且在检查 State Table 时它显示失败并有类似

的错误消息
"FailedAt":"2017-10-12T07:55:00.3075439Z",
  "ExceptionType":"System.MissingMethodException",
  "ExceptionMessage":"Cannot create an instance of an interface.",
  "ExceptionDetails":"System.MissingMethodException: Cannot create an instance of an interface.\r\n  
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)\r\n  
    at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n  
     at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n 
       at System.Activator.CreateInstance(Type type, Boolean nonPublic)\r\n   at System.Activator.CreateInstance(Type type)\r\n   at Hangfire.JobActivator.ActivateJob(Type jobType)\r\n   
       at Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type)\r\n   at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)\r\n   
       at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.<PerformJobWithFilters>b__0()\r\n   
       at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)\r\n   
       at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_1.<PerformJobWithFilters>b__2()\r\n   
       at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)\r\n   
       at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)\r\n   
       at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)"

使用的代码:

    public partial class Startup
        
            public void Configuration(IAppBuilder app)
            
                ConfigureAuth(app);
 GlobalConfiguration.Configuration.UseSqlServerStorage("ERPContext");

                RecurringJob.AddOrUpdate<IAPIRequest>(x => x.ProcessCurrencyConversion(), Cron.MinuteInterval(1));
                app.UseHangfireDashboard();
                app.UseHangfireServer();

            
        

具有要执行的方法的接口和类

 public interface IAPIRequest
    
        void ProcessCurrencyConversion();
    

 public class APIRequest : IAPIRequest
    
        public void ProcessCurrencyConversion()
        
           WebClient client = new WebClient();

            string urlPattern = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22USDKWD,EURKWD,GBPKWD,AEDKWD,ZARKWD%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";

            var jsonResult = client.DownloadString(urlPattern);
            dynamic results = JsonConvert.DeserializeObject<dynamic>(jsonResult);
            var rates = results.rate;
            List<CurrencyJSON> currencies = new List<CurrencyJSON>();
            using (var db = new ERPContext())
            

                foreach (var rate in rates)
                
                    var currencyJson = new CurrencyJSON();//POCO
                    currencyJson.Bid = rate.Bid;
                    currencyJson.Name = rate.Name;

                    currencies.Add(currencyJson);
                

                db.Configuration.AutoDetectChangesEnabled = false;
                db.Configuration.ValidateOnSaveEnabled = false;

                db.CurrencyJson.ToList().AddRange(currencies);
                db.SaveChanges();
            
        
    

我做错了什么? 感谢任何帮助,在此先感谢。 已经检查过here 发布的类似问题,但没有帮助。

【问题讨论】:

Hangfire 似乎默认不支持接口,而是需要 IoC 库将接口映射到类型。见discuss.hangfire.io/t/architecture-questions/1167/2 和discuss.hangfire.io/t/cannot-create-an-instance-of-an-interface/…。 【参考方案1】:

正如@Diado 在 cmets 中指出的那样,如果使用接口,HangFire 需要 IoC,因为没有默认支持。或者你可以直接使用类而不是接口。

https://github.com/devmondo/HangFire.SimpleInjector 是我使用的 IoC 注入器之一。

【讨论】:

以上是关于使用 Hangfire 创建重复作业时出错的主要内容,如果未能解决你的问题,请参考以下文章

是什么原因导致天蓝色托管的hangfire作业具有这种行为?

HangFire循环作业中作业因执行时间太长未完成新作业开启导致重复数据的问题...

HangFire循环作业中作业因执行时间太长未完成新作业开启导致重复数据的问题...

当 Hangfire 并行处理多个作业时,为啥 MySQL InnoDB 会产生如此多的死锁?

hangfire 相关

如何访问失败的Hangfire作业