2017-01-26 1 views
0

이것은 제네릭과 표현식에 대한 이해가 거의 부족한 것으로 확신하지만 일단 커밋 상태에 있으면 BackgroundJob.Enqueue를 호출하기 위해 Expression<Action<T>> 목록을 작성하려고합니다.Hangfire 및 작업 단위

작업을 대기열에 넣을 수있는 코드 영역이 여러 개 있지만 코드의 다른 섹션, 특히 db에 저장 될 때까지 작업을 실제로 실행해야하는지 여부는 알 수 없습니다.

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이리스트에서 받아 들여지지 않을 것임을 언급 할 필요는 없다.

+0

당신이 몇 가지 예제를 가지고 있나요 당신이 겪고있는 이슈를 요약 한 코드? – Tom

답변

1

아마도 Enqueue은 매개 변수로 Expression<Action> 소요 - 즉 없는 파라미터 소요 보이드 방법으로 계산하는 식이다.

대신 Expression<Action<T>>을 전달하려고합니다. 즉, 하나의 매개 변수이 인 void 메소드를 평가합니다. 컴파일러는 결코 그것을 허용하지 않을 것입니다. 대신

사용 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); 
     } 
    } 
} 

는 람다 구문을 사용하여, 당신의 방법을 추가 할 수 Expression<Action> 개체를 만들 수있는 당신이 대기열에 원하는 코드를 호출합니다

HangfireQueue q = new HangfireQueue(); 

q.EnqueueTask(AnyMethod, anyParameter); 

q.EnqueueTask(() => 
{ 
    AnyMethod(anyParameter); 
    OtherMethod("hello", "world"); 
}); 

q.CommitUnitOfWork(); 
+0

그래, 표현식 함께 작동했다 그러나 이것은 인터페이스 사용을 허용하지 않습니다, 내 경우에는 내가 괜찮아요, 이후 IOC 구현을 제어 할뿐만 아니라 것 같아요. 나는'q.EnqueueTask (i => i.DoSomething ("foo")); ' 그러나 당신이 말하는 것처럼 그것은 효과가 있습니다. – swhite

+0

* i * 값은 어디서 오는 것입니까? 그 행동을 실행하는 데 필요합니다. – buffjape

+1

IOC은 Hangfire 클라이언트에서 IDoSomething – swhite

관련 문제