2017-11-28 1 views
0

설명서에 따라 BackgroundWorker.RunWorkerCompleted 이벤트에서 UI에 액세스 할 수 있습니다. 하지만 콘솔 응용 프로그램에서 내 실험에 따르면 주 스레드와 RunWorkerCompleted 스레드는 다릅니다 (스레드 ID가 다르기 때문에). UI 업데이트에는 허용되지 않습니다. 이 상황을 설명하는 방법?BackgroundWorker.RunWorkerCompleted에서 UI를 업데이트 할 수 있습니까?

static BackgroundWorker _bw = new BackgroundWorker(); 

     static void Main(string[] args) 
     { 
      _bw.DoWork += DoWork; 
      _bw.WorkerReportsProgress = true; 
      _bw.RunWorkerAsync("hello"); 
      _bw.RunWorkerCompleted += _bw_RunWorkerCompleted; 
      _bw.ProgressChanged += _bw_ProgressChanged; 
      Console.WriteLine("done "+ Thread.CurrentThread.ManagedThreadId); 

      Console.ReadLine(); 
     } 



     private static void _bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      Console.WriteLine("RunWorkerCompleated " + Thread.CurrentThread.ManagedThreadId); 
     } 

     private static void DoWork(object sender, DoWorkEventArgs e) 
     { 
      Console.WriteLine(e.Argument+ " "+Thread.CurrentThread.ManagedThreadId); 
     } 

출력 :

done 1 
hello 3 
RunWorkerCompleated 5 
+0

당신이 뭘하려고하고 어떤 문제가 발생했는지 명확하게 설명 할 수 있습니까? –

답변

2

귀하의 코드가 UI를 스레드하지 않습니다. 에 UI 스레드가이 아니며 RunWorkerAsync에서으로 UI 스레드 (이벤트 처리기를 마샬링 할 UI 스레드를 알기 위해 필요함)를 호출하지 않았으므로 (존재하지 않는) UI 스레드의 이벤트 핸들러.

UI 응용 프로그램 (예 : winforms 또는 WPF 응용 프로그램)을 만들고 UI 스레드에서 BGW를 만들고 실행 한 다음 다양한 이벤트 (다른 ​​이벤트에서 컨트롤을 조작 할 수 있음을 확인하십시오 분명히 DoWork보다).

0

예 UI 스레드가있는 경우 BackgroundWorker.RunWorkerCompleted에서 UI에 액세스 할 수 있습니다.

콘솔 응용 프로그램이 별도의 스레드에서 이벤트를 실행하는 이유는 콘솔 응용 프로그램에 SynchronizationContext가 없기 때문입니다. 이는 비동기 작업을 위해 스레드 전환을 관리하는 역할을합니다.

+2

BGW는 이벤트 핸들러를 마샬링하기 위해'Dispatcher '를 사용하지 않습니다. 현재 SynchronizationContext를 사용합니다. – Servy

+0

@Servy thx 및 고정 – Steve