2011-10-01 7 views
3

나는 다음과 같은 코드를 사용했다.동기화 된 메서드를 비동기 적으로 호출하는 적절한 방법입니까?

handler.Invoke(sender, e); 

그러나이 코드의 문제는 그것이 동기적이고 모든 것이 실제로 GUI를 업데이트한다는 것이다. 서버가 완료 될 때까지 기다릴 필요가 없기 때문에 비동기로 만들어야합니다.

이 경우 콜백 메서드가 필요하지 않기 때문에 BeginInvoke 및 EndInvoke를 사용하고 싶지 않습니다.

이 방법이 적합한 대안입니까?

Task.Factory.StartNew(() => handler.Invoke(sender, e)); 
+0

'처리기'는 어떤 유형입니까? – svick

+0

@svick :'EventHandler ' –

+0

생각하고있는 모든 것이 실제로 작동하지 않습니다. UI 스레드에서 코드를 실행하려면 선택한 UI 라이브러리와 상관없이 Dispatcher.Invoke 또는 Control.BeginInvoke()를 사용하십시오. –

답변

0

당신이 괜찮했던 방법, .NET 3.5에서 작동하는이가 ThreadPool 클래스 대신 또한 핸들러가이 컨트롤에서 파생 될 일 경우

ThreadPool.QueueUserWorkItem(new WaitCallback((a) => handler.Invoke(sender, e))) 

, you are allowed to call BeginInvoke without a corresponding EndInvoke.

을 사용 할 수있는 또 다른 방법
-1

저는 C# 4의 Task 클래스에는 익숙하지 않지만 BeginInvoke가 EndInvoke없이 잘 작동한다는 것을 알고 있습니다. 나는 가끔 이런 식으로 코드를 작성 :

handler.BeginInvoke(sender, e, null, null); 

편집 : 내가 잘못했다. EndInvoke가 코드를 새 스레드에서 실행하게하는 데 필요하지는 않지만 문서에는 EndInvoke가 중요하다는 내용이 명확하게 나와 있습니다.

+2

이 코드를 사용하면'handler'에 의해 던져진 모든 예외는 자동으로 무시됩니다. 그래서 이것을하고 싶다면 자신이하는 일을 더 잘 알아야합니다. – svick

+0

@Joshua : BeginInvoke 호출은 설명서에 명시된대로 EndInvoke 호출로 끝나야합니다 (일반적으로 콜백에 배치됨). –

+0

@svick : 좋은 지적. 그래도 Task.Factory.StartNew는 예외를 throw하는 스레드에서만 catch 될 수 있으므로 동일한 문제가 발생해야합니다. 당신은 당신이 무엇을하고 있는지 알 필요가 있습니다. –

0

GUI 호출은 GUI 스레드에서 항상 수행되어야한다는 점에서 특별합니다. 자신의 말대로, handler.Invoke(sender, e)은 "GUI를 업데이트합니다", 아직 (아마) GUI 스레드에서 실행되지 않으므로 현재 양식에서는 OK가 아닙니다.

WinForms에서는 작업 위임을 Control.Invoke에 랩핑해야합니다 (또는 작업을 잊어 버리고 Control.BeginInvoke 만 사용하면됩니다).

WPF 인 경우 Dispatcher.Invoke에 작업 위임을 래핑하거나 작업없이 Dispatcher.BeginInvoke을 사용할 수 있습니다.

+0

나는 이벤트 처리기 내에서 이미 그렇게하고있다. 비동기 적으로 이벤트 처리기를 호출해야하는지 궁금 해서요. 그렇다면 원래 게시 된 코드가 그렇게하는 것이 적절한 지 궁금합니다. –

관련 문제