2013-08-03 2 views
1

조건부 연속성이있는 작은 작업 체인을 만들었지 만 약간의 동작이 발생했습니다. 내 체인은 다음과 같습니다작업 계속 이상한 동작

LoadSettings (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
CheckForUpdates (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
Update (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
Cleanup (OnlyOnFaulted)-> ErrorHandler (none)-> Exit 
| (OnlyOnRanToCompletion) 
Exit 

나는이 체인이 asynchronically 실행해야 알 수있는 바와 같이 (즉,하지 UI 스레드에서)하지만, 다른 후 하나 (그래서 LoadSettings -> CheckForUpdates -> ...).
그러나이 동작은 다음과 같습니다.
LoadSettings -> CheckForUpdates -> Cleanup -> Exit -> Cleanup -> ... 또한 첫 번째 정리는 작업 ID 1을 매개 변수로 사용하여 호출됩니다 이전에, 맞습니까?)이 작업의 상태는 취소됨 (그리고 나는 어느 곳에서나 작업을 취소하지 않습니다).
여기에 무슨 일이 벌어지고 있는지 아는 사람이 있습니까?

편집 : 계속을위한 조건이 충족되지 않으면 msdn에 따라 작업이 취소됩니다. 그래서 ErrorHandler는 취소 되나 어떻게 전체 체인을 멈출 수 있습니까? (또는 정리가 끝난 다른 연속체에 알리고 취소되었습니다)?

답변

0

Task.WhenAny을 사용하면 성공 처리기 또는 오류 처리기가 완료 될 때 실행되는 작업을 만들 수 있습니다. 그 일을 마치면 Cleanup으로 계속됩니다.

연속 체인을 올바르게 설정하는 것이 까다로운 경우가 있지만 Task.WhenAny과 같은 연결 기능을 사용하여 매우 복잡한 흐름 그래프를 만들 수 있습니다.

비동기/대기 모드를 사용할 수 있으면 작업이 훨씬 간단 해집니다. 그런 다음 정상적인 제어 흐름 구성을 사용할 수 있습니다. 반복자를 사용하여 기다릴 수도 있습니다.

0

ErrorHandler -> Cleanup continuation을 OnlyOnRanToCompletion 또는 NotOnCanceled로 설정하면 작동합니다. 또한 비동기로 작업을 단순화 할 수도 있습니다. 이 같은 뭔가 일할 수 : 당신이 마지막으로/캐치에서 기다리고 차단할 수 없기 때문에 오류 처리 및 정리, 여기에 동기 될 것이라고

try { 
    var settings = await LoadSettings(); 
    var updatesNeeded = await CheckForUpdates(settings); 
    await Update(updatesNeeded); 
} catch (Exception e) { 
    ErrorHandler(e); 
} finally { 
    Cleanup(); 
} 

참고. 변수에 예외 만 저장하면 나중에 null을 확인하고 비동기 오류 처리기로 전달할 수 있습니다.