我确信这主要是因为我对泛型和表达式缺乏理解,但我正在尝试创建一个Expression<Action<T>>列表,以便在我处于提交状态时调用BackgroundJob.Enqueue。
我有几个区域的代码可能想要将作业排入队列,但他们不知道作业是否应该真正运行,直到代码的另一部分发生,特别是对数据库的保存。
我正在努力的是在T明显不同的时候创建一个List<Expression<Action<T>>>,并在准备好的时候将它传递给BackgroundJob.Enqueue。
public class HangfireQueue
{
private readonly IList<Expression<Action<object>>> _queuedItems;
public HangfireQueue()
{
_queuedItems = new List<Expression<Action<object>>>();
}
public virtual void EnqueueTask<T>( Expression<Action<T>> methodCall )
{
_queuedItems.Add( methodCall );
}
public void CommitUnitOfWork()
{
foreach ( var item in _queuedItems )
{
BackgroundJob.Enqueue( (Expression<Action>) item );
}
}
}我尝试了许多不同的方法,这是最新的尝试,有时我编译它,但它在运行时不喜欢它,无法将Expression<Action<T>>转换为Expression<Action>将是这里的问题的一部分,更不用说列表中不接受methodCall了。
发布于 2017-01-26 18:13:35
假设Enqueue接受一个Expression<Action>作为参数-这是一个表达式,它的计算结果是一个空方法,它接受,不带参数。
您正在尝试传递Expression<Action<T>> -计算结果为一个方法,该方法只接受一个参数。编译器永远不会允许这样做的。
请改用Expression<Action>:
public class HangfireQueue
{
private readonly IList<Expression<Action>> _queuedItems;
public HangfireQueue()
{
_queuedItems = new List<Expression<Action>>();
}
public virtual void EnqueueTask(Expression<Action> methodCall)
{
_queuedItems.Add(methodCall);
}
public virtual void EnqueueTask<T>(Expression<Action<T>> methodCall, T p1)
{
_queuedItems.Add(() => methodCall.Compile()(p1));
}
public virtual void EnqueueTask<T1,T2>(Expression<Action<T1,T2>> methodCall, T1 p1, T2 p2)
{
_queuedItems.Add(() => methodCall.Compile()(p1, p2));
}
public void CommitUnitOfWork()
{
foreach (Expression<Action> item in _queuedItems)
{
BackgroundJob.Enqueue(item);
}
}
}现在添加您的方法,使用lambda语法创建Expression<Action>对象,该对象将调用您想要入队的代码:
HangfireQueue q = new HangfireQueue();
q.EnqueueTask(AnyMethod, anyParameter);
q.EnqueueTask(() =>
{
AnyMethod(anyParameter);
OtherMethod("hello", "world");
});
q.CommitUnitOfWork();https://stackoverflow.com/questions/41870435
复制相似问题