2011-02-17 4 views
1

이벤트에 가입 한 대부분의 사용자가 컨트롤이지만 메서드의 호출자가 컨트롤이 아니기 때문에 UI 스레드에서 이벤트를 발생시켜야하는 비동기 메서드가있는 싱글 톤 클래스에 있습니다. 호출자가 항상 컨트롤이 아니기 때문에 UI 스레드로 다시 호출 할 수는 없습니다. 대신 백그라운드 스레드를 시작하기 전에 AsyncOperation/SynchronizationContext를 사용하여 현재 스레드 컨텍스트를 얻은 다음 백그라운드 스레드에서 호출합니다 나는새 WindowsFormsSynchronizationContext 만들기

public void AsyncMethod() 
{ 
    AsyncOperation ao = AsyncOperationManager.CreateOperation(null); 
    // or SynchronizationContext ctx = WindowsFormsSynchronizationContext.Current; 

    ThreadPool.QueueUserWorkItem(delegate(objact state) 
    { 
     //do stuff 
     ao.Post(delegate(object state2) 
     { 
      // fire event 
     }, null); 
    }, null); 
} 

문제는이 AsyncOperation 가끔 나에게 새로운 환경을 제공한다는 것입니다, 또는 WindowsFormsSynchronizationContext가 null ... 좀과 같이, 포스트를 호출합니다. 나는 같은 문제를 겪고있는 다른 누군가를 발견했다. 그리고 그것은 그것이 이벤트에서 일어날 컨트롤을 만드는 메뉴 아이템을 드롭 다운하는 것과 관련이 있다고 생각한다. 어쨌든, 내 질문은 WindowsFormsSynchronizationContext가 null 인 경우, Post를 호출하기 위해 새 폼을 만들 수 있으며, UI 스레드의 컨텍스트 또는 새 스레드 컨텍스트를 만들었습니까?

+0

아니요, AsynchMethod()가 작업자 스레드에서 호출 될 때 발생합니다. Defensible .NET 동작은 정당화되지만 작동합니다. 그러나 앱의 스레딩이 제어 불능 상태에 있음을 나타냅니다. 해결 방법 (Application.OpenForms)을 찾지 말고 스레드가이 메서드를 호출하는 이유를 찾으십시오. –

답변

1

이 내가 UI 스레드에서 생성 된 타입 컨트롤의 개인 회원을 유지하는 것이 좋습니다 UI를 응용 프로그램에서 싱글이며, 모든 원용을 위해 그것을 사용하는 경우 :

  1. 것은 당신이를 필요로 할 수 있습니다 UI 스레드에서 호출 할 수있는 "초기화"메서드 (Application.Run 바로 전에)를 호출하고 동기화를 인스턴스화합니다.
  2. 또는 현재 스레드가 있는지 여부를 확인하여 단일 스레드에 처음 액세스 할 때 동기화 제어를 만들 수 있습니다. (Application.MessageLoop과 함께) 메시지 루프를 실행하고 Application.OpenForm 중 하나에서 컨트롤 작성을 호출하지 않는 경우.

주먹 방식은보다 결정적이어서 권장됩니다.