Cara menggunakan WPF Background Worker

177

Dalam aplikasi saya, saya perlu melakukan serangkaian langkah inisialisasi, ini membutuhkan 7-8 detik untuk menyelesaikan di mana UI saya menjadi tidak responsif. Untuk mengatasi ini saya melakukan inisialisasi di utas terpisah:

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

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

Saya telah membaca beberapa artikel tentang BackgroundWorkerdan bagaimana seharusnya memungkinkan saya untuk menjaga aplikasi saya responsif tanpa harus menulis utas untuk melakukan tugas yang panjang tapi saya belum berhasil menerapkannya, adakah yang bisa mengatakan bagaimana saya akan melakukan ini menggunakan BackgroundWorker?

Eamonn McEvoy
sumber
Saya menemukan tutorial ini berguna, ia memiliki beberapa contoh ringkas: elegantcode.com/2009/07/03/...
GrandMasterFlush
Saya mendapatkan kesalahan privasi saat mengklik tautan itu.
LittleBirdy

Jawaban:

319
  1. Tambahkan menggunakan
using System.ComponentModel;
  1. Nyatakan Pekerja Latar Belakang :
private readonly BackgroundWorker worker = new BackgroundWorker();
  1. Berlangganan acara:
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
  1. Terapkan dua metode:
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. Jalankan async pekerja kapan pun Anda butuhkan.
worker.RunWorkerAsync();
  1. Lacak kemajuan (opsional, tetapi sering bermanfaat)

    a) berlangganan ProgressChangedacara dan gunakan ReportProgress(Int32)diDoWork

    b) set worker.WorkerReportsProgress = true;(kredit ke @zagy)

Andrew Orsich
sumber
Apakah ada cara untuk mengakses DataContext dalam metode itu?
susieloo_
36

Anda mungkin ingin juga melihat menggunakan Taskalih-alih pekerja latar belakang.

Cara termudah untuk melakukan ini adalah dalam contoh Anda adalah Task.Run(InitializationThread);.

Ada beberapa manfaat menggunakan tugas alih-alih pekerja latar belakang. Misalnya, fitur async / await baru dalam .net 4.5 digunakan Taskuntuk threading. Berikut ini beberapa dokumentasi tentang Task https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task

Owen Johnson
sumber
11
Maaf untuk membuka utas ini, tetapi .net 4.0 dan 4.5 menambahkan beberapa hal keren yang lebih mudah digunakan daripada BackgroundWorker. Berharap untuk mengarahkan orang ke sana.
Owen Johnson
1
Sekarang jawaban ini sudah sangat tua, periksa asyncdan await. Ini adalah cara terintegrasi bahasa untuk menggunakan tugas dengan cara yang jauh lebih mudah dibaca.
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);  
            }  
        }  
    }  
} 

Juga, rujuk tautan di bawah ini Anda akan memahami konsep Background:

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

Gul Md Irsyad
sumber
3

Saya menemukan ini ( WPF Multithreading: Menggunakan BackgroundWorker dan Melaporkan Kemajuan ke link UI. ) Mengandung sisa detail yang hilang dari jawaban @ Andrew.

Satu hal yang saya temukan sangat berguna adalah bahwa thread pekerja tidak dapat mengakses kontrol MainWindow (dalam metode itu sendiri), namun ketika menggunakan delegasi di dalam pengendali event windows utama itu mungkin.

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;
};
lko
sumber