WPF Arkaplan Çalışanı nasıl kullanılır


177

Uygulamamda bir dizi başlatma adımı gerçekleştirmem gerekiyor, bunların tamamlanması 7-8 saniye sürüyor ve kullanıcı arayüzüm yanıt vermiyor. Bu sorunu çözmek için başlatma işlemini ayrı bir iş parçacığında gerçekleştiriyorum:

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

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

BackgroundWorkerUzun görevler yapmak için bir iş parçacığı yazmak zorunda kalmadan uygulamamın yanıt vermem için nasıl ve bana izin vermesi gerektiği hakkında birkaç makale okudum, ancak uygulamayı denemek için herhangi bir başarı elde etmedim, kimse nasıl yapacağımı söyleyebilir kullanarak BackgroundWorker?


Bu eğitimi faydalı buldum, birkaç kısa örneği var: elegantcode.com/2009/07/03/…
GrandMasterFlush

Bu bağlantıyı tıklarken gizlilik hatası alıyorum.
LittleBirdy

Yanıtlar:


319
  1. Kullanarak ekle
using System.ComponentModel;
  1. Arkaplan Çalışanı Bildir :
private readonly BackgroundWorker worker = new BackgroundWorker();
  1. Etkinliklere abone olun:
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
  1. İki yöntem uygulayın:
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. İhtiyacınız olduğunda işçi zaman uyumsuzluğunu çalıştırın.
worker.RunWorkerAsync();
  1. İlerlemeyi izleyin (isteğe bağlı, ancak genellikle yararlıdır)

    a) abone ProgressChangedolayı ve kullanımda ReportProgress(Int32)içindeDoWork

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


Bu yöntemlerde DataContext'e erişmenin bir yolu var mı?
susieloo_

36

Ayrıca Taskarka plan çalışanları yerine kullanmaya da bakmak isteyebilirsiniz .

Bunu yapmanın en kolay yolu örneğinizdir Task.Run(InitializationThread);.

Arka plan çalışanları yerine görevleri kullanmanın çeşitli faydaları vardır. Örneğin, .net 4.5 içindeki yeni zaman uyumsuz / bekliyor özellikleri Taskiş parçacığı için kullanır . Https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task hakkında bazı belgelerTask


11
Bu iş parçacığını ortaya çıkarmak için üzgünüz, ancak .net 4.0 ve 4.5, kullanımı daha kolay bazı harika şeyler ekledi BackgroundWorker. İnsanları buna yönlendirmeyi umuyorum.
Owen Johnson

1
Şimdi bu cevap çok eski, göz atın asyncve await. Bunlar, görevleri çok daha okunaklı bir şekilde kullanmanın dile entegre yollarıdır.
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);  
            }  
        }  
    }  
} 

Ayrıca, aşağıdaki kavramları anlayacağınız aşağıdaki bağlantıya bakın Background:

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


3

Bunu ( Andrew'in cevabında eksik olan ayrıntıların geri kalanını içerecek şekilde buldum) ( WPF Multithreading: BackgroundWorker'ı Kullanma ve İlerlemeyi UI'ye Bildirme. Bağlantı ).

Çok yararlı bulduğum bir şey, işçi iş parçacığı MainWindow'ın denetimlerine (kendi yönteminde) erişemedi, ancak ana windows olay işleyicisi içinde bir temsilci kullanırken mümkün oldu.

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;
};
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.