2009-12-22 4 views
3

나는 Windows Form과 비 결정적 방식으로 재귀 적으로 실행되는 두 개의 간단한 메서드가있는 클래스가 있습니다. 즉, 어떤 재귀 호출이 호출되는지, 둘 다 호출 될 수 있는지 여부를 알 수 없음을 의미합니다 ... 이제 해당 재귀 중 몇 가지 점이 있습니다. 실행을 일시 중지하고 사용자가 "다음 단계"버튼을 클릭하기를 기다리고 싶습니다. 버튼을 누른 후에 만 ​​재귀 함수가 계속됩니다. 클래스는 별도의 스레드에서 실행되므로 UI를 차단하지 않습니다.배경 스레드를 일시 중지 한 다음 단추를 클릭 할 때 계속 진행 하시겠습니까?

일시 중지 중에 Form은 클래스에서 값을 검색하여 목록 상자에 표시합니다. 그런 다음 버튼을 누르면 재귀는 다음 일시 중지()까지 계속됩니다. 사용자가 재귀 단계에서 어떤 일이 일어나는지를 단계별로 볼 수 있도록하려면 이렇게해야합니다. 또한 어떤 부작용없이 재귀 메서드 (심지어 여러 번)에 Pause()를 넣을 수 있어야합니다. ...

내 마음에 오는 유일한 방법은 Pause() 메서드를 호출하는 것입니다. 어떤 루프가 잠긴 플래그를 확인한 다음 잠시 동안 잠자기 (버튼에서 플래그를 설정)하지만 Windows Forms (UI 잠금)에서 Thread.Sleep()에 대한 몇 가지 나쁜 경험이 있었기 때문에 다른 옵션을보고 있습니다. .

이 작업을 수행 할 수있는 명확한 방법이 있습니까?

답변

6

true으로 초기화 된 ManualResetEvent을 사용하여 설정을 시작합니다. 한 가지 방법으로 잘 알려진 장소 또는 다른 곳에서 이벤트를 기다립니다. 대부분의 경우 이벤트가 설정되어 백그라운드 스레드가 즉시 계속됩니다. 그러나 사용자가 일시 중지를 클릭하면 이벤트를 재설정하므로 다음 번 이벤트에 도달 할 때 백그라운드 스레드가 차단됩니다. 사용자가 다음에 "다시 시작"을 클릭하면 은 이벤트를으로 설정하여 백그라운드 스레드가 다시 계속할 수있게합니다.

이 시나리오에서는 UI 스레드가 차단되지 않아도됩니다.

+0

사용자가 잠시 멈추지 않고 기능 자체가 일시 중지되어 약간 수정되었습니다. 사용자는 단계 만 수행합니다. 하지만 Reset()과 WaitOne()을 일시 중지()에 놓은 다음 버튼을 클릭하면 Set()가됩니다. 의도적으로 작동합니다. 내가이 수업을 결코 알아 채지 못한 것은 재밌다. –

+0

이것이 바로 AutoResetEvent의 작동 방식입니다. 스레드가 스레드에서 성공적으로 대기하면 자동으로 재설정됩니다. –

+0

예, 내 시나리오에서 AutoResetEvent도 작동하며 실제로는 짧은 코드를 한 줄 씩 작성합니다. 그래서 이제는 Pause()에서 WaitOne()을 호출 할 수 있고 나머지 코드는 변경되지 않습니다. –

2

AutoResetEvent 개체를 사용하십시오.

일시 중지하려면 스레드에서 .WaitOne 메소드를 호출하고 버튼에서 .Set 메소드를 호출하여 일시 중지 해제하십시오.

+0

같은

. –

+0

이 시나리오에서는 작동하지 않습니다 ...? –

+0

그것은 작동합니다. 그래서 아무 이유도 없습니다 :) –

1

이것은 표준이 아닌 방식으로 뮤텍스를 사용하기에 좋은 장소입니다. 기다려도 괜찮은 위치에있을 때 배경 스레드가 뮤텍스를 가져 와서 놓아 주도록하십시오.

GUI 스레드가 백그라운드 스레드를 차단하려고 할 때 뮤텍스를 가져오고 실행하려고하면 해제하십시오.

그런 식으로 백그라운드 스레드는해야 할 때를 기다리고, 실행이 허용 될 때 뮤텍스 내외로 간단하게 블레이즈됩니다.

중요한 부분이 보호하고있는 리소스로 '실행할 권리'를 생각하십시오. 이 시나리오에서 목적으로하는`AutoResetEvent`가 작동하지 않습니다이

// this object has to be visible to both threads 
System.Threading.Mutex mtx = new Mutex(); 

// worker thread does this wherever it's ok for it to pause 
mtx.WaitOne(); 
mtx.ReleaseMutex(); 

// main thread does this to pause the worker 
Mtx.WaitOne(); 

// main thread does this this to unpause it. 
mtx.ReleaseMutex(); 
관련 문제