У меня есть функция -
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>}
🤔 А знаете ли вы, что...
C# позволяет создавать собственные библиотеки классов и использовать их в других проектах.
Перегрузка RecurringJob.AddOrUpdate
, которую вы вызываете, принимает Expression<Func<Task>>
. Это дерево выражений, представляющий вызов, который возвращает задачу.
К сожалению, RecurringJob.AddOrUpdate
требует, чтобы это дерево выражений представляло вызов метода — оно вызывает Job.FromExpression
, что в итоге приводит к этот код. Каждый Job
в конечном итоге строится из MethodInfo
. Ваше лямбда-выражение является вызовом через параметр, поэтому оно не работает.
Вы можете обернуть вызов в вызов метода, как показано ниже - я не знаю, будет ли это работать на самом деле... вы можете обнаружить, что у вас есть много заданий с именем «Выполнение».
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();
}