2011-09-24 4 views
2

라이브러리를 작성 중이며 지정된 스레드에서 콜백을 실행하고 싶기 때문에 최종 사용자는 스레드 안전성에 대해 걱정할 필요가 없습니다.지정된 스레드에서 콜백을 수행 할 수있는 방법이 있습니까?

ExecutionContext을 사용해 보았지만 너무 잘 작동하지 않아 지정된 컨텍스트 (새 스레드)에서 실행되지만 원래 해당 함수를 호출 한 스레드에서는 실행되지 않습니다. 다시 전화를받을 수 있습니다 때 보장 할 수 없습니다, 또는 어떤 스레드 당신의 콜백 함수를 실행합니다 - 비동기 기능에 대한 일을의

void Connect() { 
    // This should be in the same thread .. 
    SocketAsyncEventArgs.Completed += eventHandler; 
    Socket.ConnectAsync(SocketAsyncEventArgs) 
} 

void eventHandler() { 
    // .. as this 
} 
+1

이벤트 처리기를 작성할 때 동일한 스레드 (이벤트를 생성 한 개체를 만든 스레드) 또는 다른 스레드에서 실행되는 것으로 주석 처리합니다. 그런 다음 계약자를 읽고 그에 따라 대응하도록 소비자에게 맡깁니다 (즉, 이벤트 처리기가 적절한 스레드로 보내거나 게시해야합니다) - 때때로 UI 스레드에 제어권을 반환하는 것이 적절합니다. SynchronizationContext) 다른 시간에는 * 매우 나쁘고 * 교착 상태가 발생할 수 있습니다. –

+0

이 경우 주석은 어떻게 도움이됩니까? 프레임 워크 및/또는 OS가 적절한 스레드에서 이벤트 처리기를 호출합니까? – cHao

+0

@cHAo "나는 소비자에게 맡긴다. (처리기) ..."따라서 왜 "대답"이 아닌 코멘트가 될까? –

답변

2

기존 스레드에서 코드를 실행할 수는 없습니다. 해당 스레드가 이미 다른 코드를 실행 중입니다. 하지만, 코드를 실행할 수있는 방법을 제공 할 수 있습니다. WPF 응용 프로그램의 주 스레드는 Dispatcher.Invoke()을 사용하여이 작업을 수행합니다. WinForms 응용 프로그램의 주 스레드는 Control.Invoke()을 사용합니다.

더 일반적인 방법은 다음과 같습니다. Synchronization.Context.Current을 사용하십시오. 이 WPF 또는 WinForms 응용 프로그램의 주 스레드에 대해 작동하지만 다른 스레드 풀 스레드에서 콜백을 실행합니다. (내가 생각하는 일종의 맞춤 동기화 컨텍스트가 없다면 매우 드뭅니다.)

하지만이 방법이 최선입니다. 내가 말했듯이, 당신은 원할 때 다른 스레드에서 코드를 실행할 수 없습니다. 다른 스레드의 코드는 그렇게 할 수 있어야합니다.

+0

대부분의 정보를 제공하므로 답변을 수락합니다. 라이브러리가 비동기 작업을위한 이벤트를 제대로 제공 할 수있는 방법을 조사 할 것입니다 (UI 스레드가 반드시 필요하지는 않기 때문에). –

1

을 :

코드는 다음과 같이 작동합니다. 그것이 "설정하고 잊어 버릴 수있는 비용"을 고려하십시오.

어쨌든 많은 제어가 필요하지 않습니다. 콜백을 실행하는 특정 스레드를 "필요"하게 만들려면 필요한 이유를 검토해야합니다. UI 스레드에서 실행해야하는 항목 인 경우 Control.Invoke이 있습니다. (UI 스레드는 아키텍처가 작동하는 방식 때문에 물건을 가져갈 필요가 있다고 예상하므로 컨트롤은 콜백을 해당 스레드에서 실행하는 방법을 제공합니다. 임의 스레드를 사용하여이를 수행 할 수는 없습니다. 이와 같은 콜백을 전달할 것으로 예상됩니다.) 그렇지 않으면 잠금 또는 무언가에 문제가있는 경우 비동기 기능을 사용하여 실제로 별도의 스레드에서 동 기적으로 수행해야하는 작업을 수행하려고 할 가능성이 있습니다.

관련 문제