2011-09-09 5 views
2

API 호출에 대한 네트워크 코드가있는 Outlook 용 addin을 작성 중이므로 APIWork를 캡슐화하는 BackgroundWorker 클래스를 확장하는 여러 클래스가 있습니다. 코드는 API 호출에 대해 다음과 같습니다BackgroundWorkerCompleted가 주 스레드에서 실행되지 않는 것 같습니다.

public class ApiLogin : BackgroundWorker 
{ 
    private void ThisAddInStartup(object sender, EventArgs e) 
    { 
     this.DoWork += BgWorkerDoWork; 
     this.RunWorkerCompleted += BgWorkerCompleted; 
    } 

    private void BgWorkerDoWork(object sender, DoWorkEventArgs e) 
    { 
     //Perform network call on the background thread 
     var logged_in = ApiRequests.login(); 
     e.Result = logged_in; 
    } 

    //This should run in the main thread, no? 
    private void BgWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     var logged_in = (bool)e.Result; 

     //Do stuff in main thread, hopefully.. 

     //Investigate if this runs in the main thread since it should block Outlook, no? 
     Thread.Sleep(50000); 
    } 
} 

그리고 코드는 아웃룩 추가 기능에 대해 다음과 같습니다

public class ThisAddin 
{ 

    private ApiLogin _loginWorker; 

    private void ThisAddInStartup(object sender, EventArgs e) 
    { 
     _loginWorker = new ApiLogin(); 
     _loginWorker.RunWorkerAsync(); 
    } 
} 

나는 전망 I 50여 초 동안 차단하는 기대 내 추가 기능을 실행하면 배경 작업자 Completed-event 핸들러에서 Thread.Sleep (50000)을 가지지 만, 이는 발생하지 않습니다. 이것은이 코드가 주 스레드에서 실행되지 않는다는 것을 의미합니다. 나는 헛되이 해결책을 찾았는데 이제는 문제가 될지 모르는 사람이 있는지 알고 싶습니다.

답변

3

BackgroundWorker는 동기화 공급자가 RunWorkerCompleted 이벤트가 실행되는 스레드를 결정해야합니다. SynchronizationContext.Current를 사용합니다. 플러그인 시작시이 속성이 null이라는 확률이 매우 높습니다. 따라서 아무 것도 동기화되지 않고 이벤트는 스레드 풀 스레드에서 실행됩니다.

.NET Framework에는 Winforms 용 동기화 공급자와 WPF 용 동기화 공급자가 각각 두 가지 있습니다. 스레드 마샬링을 위해 각각의 메시지 루프가 필요하며 Application.Run() 메서드에서 SynchronizationContext.Current를 할당합니다. 너도 그럴 수 없어. 가장 간단한 솔루션은 Winforms Form을 만들고 ShowDialog() 메서드를 호출하는 것입니다. 그 자체가 이미 Outlook 사용자 인터페이스를 차단합니다. 또한 사용자에게 피드백을 제공하여 Outlook이 응답하지 않는 이유를 추측 할 필요가 없습니다.

+0

매우 흥미 롭습니다. 나는 이것을보아야 할 것입니다! – nelshh

+0

당신은 정말로 옳았습니다! 고마워요! – nelshh

1

나는 정확히 ThisAddinStartup 메서드와 같은 스레드에서 실행될 것으로 기대합니다. 두 위치에서 스레드 ID를 추적하여이를 확인할 수 있습니다.

Outlook의 경우 별도의 UI 스레드에서 추가 기능을 실행하고있을 수도 있습니다.

+1

답장을 보내 주셔서 감사합니다. 내가 다른 곳에서 Thread.sleep()을 사용하면 Outlook에서 다른 스레드에서 Outlook 2007을 완전히 실행하지 않습니다. 스레드 ID를 추적하는 좋은 방법을 찾지 못했습니다. 어려울 것 같습니다. 유용한 정보가 있습니까? – nelshh

+1

아마도'Debug.Print (Thread.CurrentTread.ManagedThreadId)'? –

+0

그래, 이드가 달라졌어./왜 이럴지 몰라. – nelshh

관련 문제