2012-09-27 4 views
1

단추 클릭으로 시작되는 백그라운드 비동기 작업이 있습니다. 작업이 시작될 때 업데이트되고 finally 블록 내에 취소 또는 완료를 설명하기 위해 업데이트되는 IsBusy 속성이 있습니다.비 즉시 작업 취소, 다시 시작 및 통화 중 표시

현재 내 버튼 클릭 이벤트는 이전 작업을 취소하고 다시 클릭하면 새 작업을 시작합니다. 그러나 첫 번째 작업의 취소가 새 작업의 시작을 지나서 지날 수 있으므로 부울 IsBusy 표시기가 동기화되지 않을 수 있습니다.

내 문제는이 상황을 어떻게 처리 할 것인가입니다.

현재의 솔루션은 부울 값을 직접 업데이트하지 않고 시작 및 완료시 증가/감소하는 정수를 사용하는 것입니다. 속성은 BusyCount > 0을 반환합니다. 그러나 스레드 안전성에 대한 추가가 필요하며 좋은 솔루션이라고 생각하지 않습니다.

또 다른 생각은 해고 될 때 작업을 저장하고 첫 번째 작업의 연속으로 새 작업을 시작하는 것입니다. 이것은 취소 문제를 설명하지만 불필요한 지연 (분수)과 작업보다는 발신자에 대한 '계약'을 강제합니다.

내 마지막 생각은 스레드 세이프 컬렉션에서 추가/제거되는 일회용 BusyTokens를 나눠주는 BusyTokenSource 클래스와 같은 것을 만드는 것이 었습니다.하지만 이것은 과도한 것처럼 보입니다.

이런 상황을 처리하는 데 더 좋고/적절하며 일반적인 방법이 있습니까?

편집 : 나는 위의 내 마지막 생각으로가는 종료하고 'BusyToken'클래스를 쓴

. 이렇게하면 using(BusyTokenSource.GetToken()){}에 함수를 간단하게 래핑하고 내부 컬렉션과 Dispose이 카운팅 및 사용 중 상태를 처리하도록 할 수 있습니다.

답변

2

업무별로 업무 중 상태가 하나 있어야한다고 생각합니다. 귀하의 BusyTokenSource 아이디어가 어떻게 작동하는지 모르지만 조금 좋아 보입니다.

는 홀더 클래스 만들기 :

class BusyStatus { bool IsBusy; } 

을 그리고 시작하는 각 작업에의 새로운 인스턴스를 제공합니다. 더 이상 이전 작업에 관심이 없으면 이전 BusyStatus를 삭제하고 새 인스턴스를 만듭니다. 이전 태스크는 마침내 종료되고 사용중인 상태가되지만, 더 이상 사용하지 않는 이전 인스턴스에서 설정됩니다.

이전 작업이 실수로 새 BusyStatus 인스턴스를 참조하지 않았는지 확인하십시오.

보다 일반적인 원칙으로 각 작업 (또는 스레드)을 별개의 데이터 구조에서 작동시키는 것이 종종 유용합니다. 이것은 유용한 일반적인 지침 원리입니다. 그것은 당신에게 단순함을 얻고 안전을 달성하기 쉽게 만듭니다.

+0

응답 해 주셔서 감사합니다. 위의 제안을 통해 소유자 (내 경우 뷰 모델)의 전반적인 통화 상태를 어떻게 '집계'합니까? –

+0

@ach, "버려진"작업을 바쁘지 않은 것으로 처리 할 수 ​​있습니까? 결과가 어쨌든 버려지기 때문에 이해할 수 있습니다. 그렇지 않다면, 바쁜 작업의 수를 저장하는 동기화 된 변수 (int)가 필요할 것입니다. 나는 그 주위에 방법을 볼 수 없습니다. – usr

+0

답장을 보내 주셔서 감사합니다. 위의 편집을 추가하고 일회용 BusyToken 메서드를 사용했습니다. 그것은 위대한 작품. –