WPF 백그라운드 작업자를 사용하는 방법


177

내 응용 프로그램에서 일련의 초기화 단계를 수행해야하며 UI가 응답하지 않는 동안 완료하는 데 7-8 초가 걸립니다. 이 문제를 해결하려면 별도의 스레드에서 초기화를 수행하십시오.

public void Initialization()
{
    Thread initThread = new Thread(new ThreadStart(InitializationThread));
    initThread.Start();
}

public void InitializationThread()
{
    outputMessage("Initializing...");
    //DO INITIALIZATION
    outputMessage("Initialization Complete");
}

BackgroundWorker긴 작업을 수행하기 위해 스레드를 작성하지 않고도 응용 프로그램을 응답 가능하게 유지하는 방법 에 대한 몇 가지 기사를 읽었 지만 구현을 시도했지만 성공하지 못했습니다. 이것을 사용하여 BackgroundWorker?


: 나는 몇 가지 간결한 예제가이 튜토리얼이 유용하다고 elegantcode.com/2009/07/03/...
GrandMasterFlush

해당 링크를 클릭하면 개인 정보 오류가 발생합니다.
LittleBirdy

답변:


319
  1. 사용하여 추가
using System.ComponentModel;
  1. 백그라운드 워커 선언 :
private readonly BackgroundWorker worker = new BackgroundWorker();
  1. 이벤트 구독 :
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
  1. 두 가지 방법을 구현하십시오.
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
  // run all background tasks here
}

private void worker_RunWorkerCompleted(object sender, 
                                           RunWorkerCompletedEventArgs e)
{
  //update ui once worker complete his work
}
  1. 필요할 때마다 작업자를 비동기 적으로 실행하십시오.
worker.RunWorkerAsync();
  1. 진행 상황 추적 (선택적이지만 종종 유용함)

    A)에 가입 ProgressChanged이벤트 및 사용 ReportProgress(Int32)DoWork

    b) 설정 worker.WorkerReportsProgress = true;(크레딧을 @zagy로)


해당 메소드에서 DataContext에 액세스하는 방법이 있습니까?
susieloo_

36

Task백그라운드 워커 대신 사용하는 것이 좋습니다.

가장 쉬운 방법은 예입니다 Task.Run(InitializationThread);.

백그라운드 작업자 대신 작업을 사용하면 몇 가지 이점이 있습니다. 예를 들어 .net 4.5의 새로운 async / await 기능은 Task스레딩에 사용 됩니다. 다음은 https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task 에 대한 설명서입니다.Task


11
이 스레드를 발굴하여 죄송하지만 .net 4.0 및 4.5는보다 사용하기 쉬운 멋진 것들을 추가했습니다 BackgroundWorker. 사람들을 조종하기를 바라고 있습니다.
Owen Johnson

1
이제이 대답은 매우 오래된 것으로, 체크 아웃 async하고 await. 이것들은 훨씬 더 읽기 쉬운 방식으로 작업을 사용하는 언어 통합 방법입니다.
Owen Johnson

14
using System;  
using System.ComponentModel;   
using System.Threading;    
namespace BackGroundWorkerExample  
{   
    class Program  
    {  
        private static BackgroundWorker backgroundWorker;  

        static void Main(string[] args)  
        {  
            backgroundWorker = new BackgroundWorker  
            {  
                WorkerReportsProgress = true,  
                WorkerSupportsCancellation = true  
            };  

            backgroundWorker.DoWork += backgroundWorker_DoWork;  
            //For the display of operation progress to UI.    
            backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;  
            //After the completation of operation.    
            backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;  
            backgroundWorker.RunWorkerAsync("Press Enter in the next 5 seconds to Cancel operation:");  

            Console.ReadLine();  

            if (backgroundWorker.IsBusy)  
            { 
                backgroundWorker.CancelAsync();  
                Console.ReadLine();  
            }  
        }  

        static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)  
        {  
            for (int i = 0; i < 200; i++)  
            {  
                if (backgroundWorker.CancellationPending)  
                {  
                    e.Cancel = true;  
                    return;  
                }  

                backgroundWorker.ReportProgress(i);  
                Thread.Sleep(1000);  
                e.Result = 1000;  
            }  
        }  

        static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)  
        {  
            Console.WriteLine("Completed" + e.ProgressPercentage + "%");  
        }  

        static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)  
        {  

            if (e.Cancelled)  
            {  
                Console.WriteLine("Operation Cancelled");  
            }  
            else if (e.Error != null)  
            {  
                Console.WriteLine("Error in Process :" + e.Error);  
            }  
            else  
            {  
                Console.WriteLine("Operation Completed :" + e.Result);  
            }  
        }  
    }  
} 

또한 아래 링크를 참조하면 다음과 같은 개념을 이해할 수 있습니다 Background.

http://www.c-sharpcorner.com/UploadFile/1c8574/threads-in-wpf/


3

나는이 (발견 WPF 멀티 스레딩을. : 링크를 BackgroundWorker에 사용하고 UI로 진행보고 ) 앤드류의 대답 @에서 누락 된 세부 사항의 나머지 부분을 포함 할 수 있습니다.

내가 매우 유용하다고 생각한 것은 작업자 스레드가 MainWindow의 컨트롤에 액세스 할 수 없다는 것입니다 (자체의 방법으로)하지만 주 Windows 이벤트 핸들러 내에서 대리자를 사용할 때 가능했습니다.

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    pd.Close();
    // Get a result from the asynchronous worker
    T t = (t)args.Result
    this.ExampleControl.Text = t.BlaBla;
};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.