C# 将方法传递给Hangfire Scheduler的另一个方法,而不是使用硬编码的方法名

C# 将方法传递给Hangfire Scheduler的另一个方法,而不是使用硬编码的方法名,c#,hangfire,C#,Hangfire,我正在使用Hangfire并试图安排一个简单的工作。如果我在指定的时间硬编码要触发的方法的名称,它就可以工作,但我希望有更通用的方法,即将任何方法传递到此代码中,并让Hangfire按计划执行它 这是我尝试的方法之一 public static void ScheduleSingleRun(Activity parametersStorage, Action<Activity, int> scheduledFunction, int secondsDelay) { TimeS

我正在使用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);          
        ... 
其中TestMethod是同一类中方法的名称

此代码可编译,但在运行时会导致此错误:

Expression body should be of type `MethodCallExpression`"
我尝试了行动、函数、委托-没有任何效果。仅指定显式方法名称有效:

BackgroundJob.Schedule(() => TestClass.TestMethod(parametersStorage, secondsDelay)

我做错了什么?有没有办法只将方法名/引用传递给Hangfire,而不是硬编码?

请参见下面的示例。在你的情况下,我认为你必须传递一个表达式。在我的示例中,应该将“lambda”变量传递给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());
    }
}
类程序
{
静态void Main(字符串[]参数)
{
int param1Value=2;
对象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=表达式.lambda(exp,param1,param2);
lambda.Compile().Invoke(param1Value,param2 value);
}
}
静态类MyClass
{
公共静态void TestMethod(int-param1,object-param2)
{
控制台写入线(参数1);
Console.WriteLine(param2?.ToString());
}
}

看看这个异常,我认为您应该传递类似以下内容:System.Linq.Expressions.Expression.Call(…);基本上你必须传递一个表达式。手动创建自己的表达式树并传递它。more info here=>可能重复一件事,因为默认情况下,反射只搜索公共方法,它不需要传递BindingFlags.public | BindingFlags.Static:
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());
    }
}