我有一个函数-
public async Task DoWork(Frequency value) { // do work }
这里的想法是将此函数作为循环作业添加到Hangfire。
添加作业显式地工作,像这样-
RecurringJob.AddOrUpdate("triggerId", () => DoWork(frequency), Cron.Daily())
但是,如果我想创建一个函数来添加触发器
private void AddTrigger(string triggerId, Frequency frequency, Func<Frequency, Task> trigger)
{
RecurringJob.AddOrUpdate(triggerId, () => trigger(frequency), Cron.Daily());
}
我得到一个错误Expression body should be of type 'MethodCallExpression'
当我调试时,它们似乎是相同类型的对象。我在这里遗漏了什么导致这个错误?
() => trigger(frequency) {Method = {System.Threading.Tasks.Task <<>m0>b__0()}} object {System.Func<System.Threading.Tasks.Task>}
() => DoWork(frequency) {Method = {System.Threading.Tasks.Task <<>m0>b__0()}} object {System.Func<System.Threading.Tasks.Task>}
您正在调用的RecurringJob.AddOrUpdate
过载接受Expression<Func<Task>>
。这是一个表达式树,表示返回任务的调用。
不幸的是,RecurringJob.AddOrUpdate
需要表达式树来表示一个方法调用—它调用Job.FromExpression
,最终在此代码中结束。每个Job
最终都是由MethodInfo
构建的。您的lambda表达式是通过参数调用的,因此它不起作用。
你可以将调用包装在一个方法调用中,如下所示-我不知道它是否会实际工作…你可能会发现你最终有很多工作的名字都是"执行"。
private void AddTrigger(string triggerId, Frequency frequency,
Func<Frequency, Task> trigger)
{
var wrapper = new TriggerWrapper(() => trigger(frequency));
RecurringJob.AddOrUpdate(triggerId, () => wrapper.Execute(), Cron.Daily());
}
private class TriggerWrapper
{
private Func<Task> func;
internal TriggerWrapper(Func<Task> func) => this.func = func;
public Task Execute() => func();
}