我正在使用Hangfire,并试图安排一份简单的工作。如果我在指定的时间硬编码要触发的方法的名称,它会工作,但我想要更通用的东西,即将任何方法传递到此代码中,让Hangfire按计划执行它。
这是我尝试这样做的方法之一。
public static void ScheduleSingleRun(Activity parametersStorage, Action<Activity, int> scheduledFunction, int secondsDelay)
{
TimeSpan offset = new TimeSpan(0, 0, secondsDelay);
try
{
BackgroundJob.Schedule(() =>
scheduledFunction(parametersStorage, secondsDelay), offset);
return new HangfireSchedulerResponse("Scheduled successfully.", 0);
...
这就是我如何称呼这个功能:
HangfireScheduler.ScheduleSingleRun(parameters, TestMethod, 15);
其中TestMethod是同一类中方法的名称。
此代码编译,但在运行时会导致此错误:
Expression body should be of type `MethodCallExpression`"
我尝试了Action,Func&lt;&gt;,代表 - 没有任何效果。仅指定显式方法名称有效:
BackgroundJob.Schedule(() => TestClass.TestMethod(parametersStorage, secondsDelay)
我做错了什么 - 有没有办法将方法名称/引用传递给Hangfire而不是硬编码?
答案 0 :(得分:1)
请参阅下面的示例。在你的情况下,我认为你必须传递一个表达式。在我的例子中,你应该通过&#34; lambda&#34;变量到您的BackgroundJob.Schedule方法。
class Program
{
static void Main(string[] args)
{
int param1Value = 2;
object param2Value = "hello";
var param1 = Expression.Parameter(typeof(int));
var param2 = Expression.Parameter(typeof(object));
var testMethodInfo = typeof(MyClass).GetMethod("TestMethod", BindingFlags.Public | BindingFlags.Static);
var exp = Expression.Call(testMethodInfo, param1, param2);
var lambda = Expression.Lambda<Action<int, object>>(exp, param1, param2);
lambda.Compile().Invoke(param1Value, param2Value);
}
}
static class MyClass
{
public static void TestMethod(int param1, object param2)
{
Console.WriteLine(param1);
Console.WriteLine(param2?.ToString());
}
}