2011-08-03 2 views
2

길이를 줄일 수있는 방법이BackgroundWorker.CancellationPending체크 포인트에 있습니까?C# BackgroundWorker 취소 검사 점 단축

//PSUEDO METHOD 
//DO NOT TAKE THIS AS REPEATING CODE 
//IT IS ONLY MEANT TO SHOW MULTIPLE USES OF THE SAME CHECKPOINT 
//MY REAL TASK METHOD(S) CONTAIN MANY MANY MANY AREAS THAT DON'T REPEAT AND REQUIRE CHECKPOINTS 
public void FakeBWTask() 
{ 
    if (this.TW.CancellationPending) 
     return; 

    foreach (var F1 in Fake1) 
    { 
     if (this.TW.CancellationPending) 
      return; 

     foreach (var F2 in Fake2) 
     { 
      if (this.TW.CancellationPending) 
       return; 
      foreach (var F3 in Fake3) 
      { 
       if (this.TW.CancellationPending) 
        return; 
      } 
     } 
    } 
} 
:

예를 들어, 나는이 같은 멀티 체크 포인트 상황을 더 쉽게 읽을 수 있도록하기 위해 노력하고있어?

//REAL CODE (CURRENTLY USE THIS) 
if (this.TW.CancellationPending) 
    return; 

//PSEUDO REPLACEMENT CODE 
this.CkPt(CurrentMethod); //PSEUDO USAGE 
    //^^^ PARAMETER IS A REFERENCE TO THE CURRENT METHOD, SIMILAR TO `this` FOR AN OBJECT 
//OR MAYBE AN EXTENSION METHOD WOULD LOOK CLEANER 
CurrentMethod.CkPt(); //PSEUDO USAGE 

private void CkPt(Method m) //PSEUDO METHOD 
{ 
    /* 
     POSSIBLY PERFORM OTHER CHECKPOINT TASKS HERE 
    */ 
    if (this.TW.CancellationPending) 
     m.return/*FROM METHOD THAT CALLED ME*/; 
} 

아래의 예제 코드 return를 캡슐화하는 방법은 무엇입니까

도움 주셔서 감사합니다 !!

+0

Hmya, 물론 어색한 코드. 스레드에 예외를 주입하는 것은 모두가 좋아하는 허풍이다. 쓰레드 취소가 인간의 지각 시간보다 더 효과적이라는 것은 정말로 중요한 일인가? 50 밀리 초는 CPU 사이클의 hellofalot입니다. –

+0

이벤트가 발생하는 것을 중지하는 것입니다. 실제 코드에서는 이벤트가 50 밀리 초보다 훨씬 길다. 나는 두 번째 코드를 거기에 두어서는 안됩니다. 그 질문을 망치고있어. – PiZzL3

답변

5

이 같은 반복자를 사용하는 것을 고려 methodB를 호출하고 (우리가 꼬리 재귀를 가지고 있지 않기 때문에) methodB가 methodA를 반환 할 수 있도록 methodA있는 방법 호출이 없습니다. 체크 포인트 사이에 try/catch를 넣을 수있는 경우도 있습니다.

public void FakeBWTask() 
{ 
    if (this.TW.CancellationPending) 
     return; 
    foreach (object ignore in FakeBWTaskSteps()) 
    { 
     // Other checkpoint logic here.... 
     if (this.TW.CancellationPending) 
      return; 
    } 
} 

private IEnumerable<object> FakeBWTaskSteps() 
{ 
    Part1(); 
    yield return null; // Execute checkpoint logic. 

    Part2(); 
    yield return null; // Execute checkpoint logic. 

    Part3(); 
    yield return null; // Execute checkpoint logic. 

    Part4(); 
    yield return null; // Execute checkpoint logic. 

    // Do some other stuff. 
    yield return null; // Execute checkpoint logic. 

    // final stuff. No looping here. 
} 
+0

예제 코드가 명확하지 않아 죄송합니다. 나는 반복적으로 취해 지도록 의도되지 않은 반복 코드를 빠르게 작성했습니다. 그것을 반복하는 것은 내가 찾고있는 것이 아니며 내 질문에 답하지 않습니다. 내 REAL 코드가 반복되지 않고 여러 체크 포인트가 포함되어 있습니다. 위의 예를 업데이트하겠습니다. – PiZzL3

+0

@ PiZzL3, 체크 포인트 논리가 매번 동일 할 경우이 작업이 가능합니다. 체크 포인트 논리가 다른 경우 논리를 실행할 수있는 대리자를 반환합니다. –

+0

@ PiZzLe3, 내 대답을 업데이트했지만 마크가 누락 된 이유는 아직도 알 수 없습니다. –

1

IL 재 작성을 위해 mono.Cecil을 사용할 수 있습니다. "Cancellable"속성을 가진 메소드를 꾸며서 그 속성을 가진 메소드를 다시 작성할 수 있습니다. 명령 스트림에서 CFG를 작성하고 스택 깊이를 계산하기위한 코드를 작성하고 스택 깊이가 0 인 장소를 확인하고 취소 체크를 수행 할 노드를 삽입 한 다음 CFG를 메소드 본문으로 다시 연합해야합니다. 아마도 모든 것을 테스트하는 데 약 1 주가 걸릴 것입니다. 또한 게시 빌드 단계를 추가해야합니다.

일반적으로 취소 가능한 메소드가 많지 않은 한 일반적으로 유용하지 않습니다.

+0

와우, 그런 멋진 요소를 보았습니다. (IL 코드가있는 트릭).하지만 지금은 내 머리 위로 WAYYYYYY입니다. 이제 막 고급 C# 기능의 표면을 긁어 내기 시작했습니다. – PiZzL3