2013-10-30 2 views
0

I lock의 리소스에 대한 액세스를 전역 개체에 동기화하여 제대로 작동하는 다양한 스레드의 외부 장치와 통신을 동기화합니다.UI 스레드

사용자가 slider 컨트롤에 값을 설정하여 외부 장치로 보내려고하므로 해당 장치를 보내기 전에 변경 내용을 수신하기 위해 Scroll 이벤트를 사용하고 있습니다.

private void slider_Scroll(object sender, EventArgs e) 
{ 
    lock(lockObject) 
    { 
     //send slider values to external device 
    } 
} 

위는 항상 lock을 얻기 위해 시도에 무기한 응답 : 다음과 같은 문제가

, 나는 장치와 통신하기 전에 전역 객체에 lock해야합니다. 나머지 코드는 정상적으로 작동하므로 정상적인 경쟁 조건이 없다고 생각합니다. UI 스레드에서 실행 중이며 UI 스레드에서 차단할 수있는 나쁜 아이디어라고 생각합니다. 내가 틀렸을 수도있다.

그러나이 경우 해당 메서드에서 위의 코드를 래핑하고 어떻게 든 '기본'스레드에서 호출해야합니다. UI 스레드?

어떻게하면됩니까?

답변

1

메인 UI 스레드에서 lock을 사용하는 것은 절대로 바람직하지 않습니다. 폼에 BackgroundWorker() 컨트롤을 추가하고 슬라이더 값을 RunWorkerAsync() 메서드에 전달합니다. e.Argument을 통해 DoWork() 핸들러의 값을 검색하고 거기에서 lock을 안전하게 사용할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 아마도 이것이 효과가있을 것이라고 상상해 봅니다. 슬라이더를 이동할 때마다 BackgroundWorker를 회전시키는 데 많은 오버 헤드가 있습니까? 대신 대리인을 사용할 수 있습니까? –

+0

BackgroundWorker()가 이미 실행 중일 때 다시 실행하려고하면 예외가 발생합니다. IsBusy() 속성을 검사하여 실행 여부를 결정할 수 있습니다. 방법이 어떻든간에 컨트롤이 변경되지 않고 마지막 값만 전송 될 때까지 기다리는 것이 더 합리적 일 수 있습니다. 정확히 어떤 컨트롤을 사용하고 있습니까? ... "슬라이더"는 여러 가지 다른 것들일 수 있습니다. –

+0

Windows Form '슬라이더'. 마지막 값을 보내 주면 간단합니다. 내 외부 장치에서 값을 읽으려면 BackgroundWorker의 RunWorkerCompleted 이벤트를 통해 UI 요소에 값을 반환해야한다고 생각합니다. –