Hangfire通过反序列化对象入队后台作业时InvocationData生成异常问题
问题分析与解决方案
你的问题核心在于泛型方法的类型推断机制:当你调用EnqueueAsync(obj)时,obj在编译时的类型是object,所以泛型参数TArgs被推断为object,导致Hangfire生成的InvocationData里使用了System.Object的类型信息,而不是你反序列化得到的实际类型MyAssembly.BackgroundJobs.MyClass。
要解决这个问题,你需要通过反射动态调用泛型版本的EnqueueAsync方法,让泛型参数指定为反序列化对象的真实类型。
修改后的代码实现
调整你的JobExecuter中的ExecuteAsync方法,替换原来的EnqueueAsync调用逻辑:
public async Task ExecuteAsync() { var item = await backgroundJobInboxRepository.FirstOrDefault(); var type = Type.GetType(item.AssemblyName); var obj = jsonSerializer.Deserialize(type, item.Arguments, false); // 获取EnqueueAsync的泛型方法定义 var enqueueMethod = typeof(IBackgroundJobManager) .GetMethod(nameof(IBackgroundJobManager.EnqueueAsync)) .MakeGenericMethod(type); // 调用泛型方法,传入参数:obj、默认优先级、null延迟 await (Task<string>)enqueueMethod.Invoke(backgroundJobManager, new object[] { obj, BackgroundJobPriority.Normal, null }); }
为什么这样能解决问题?
MakeGenericMethod(type)会根据你动态获取的MyClass类型,构建出EnqueueAsync<MyClass>的具体泛型方法。- 通过反射调用这个泛型方法时,Hangfire就能正确识别到参数的真实类型,生成符合你期望的
InvocationData,其中类型信息会是MyAssembly.BackgroundJobs.MyClass而非System.Object。
额外注意事项
- 确保
Type.GetType(item.AssemblyName)能正确加载到目标类型(注意程序集名称的拼写、版本号等是否准确)。 - 如果你的
EnqueueAsync方法有重载,需要用更精确的方式获取方法(比如指定参数类型),不过从你提供的HangfireBackgroundJobManager实现来看,当前的方法获取方式是可行的。
内容的提问来源于stack exchange,提问作者Adem Aygun
相关产品推荐
相关产品推荐

