Как использовать WPF Background Worker - PullRequest
173 голосов
/ 30 марта 2011

Я новичок с WPF , в моем приложении мне нужно выполнить серию шагов инициализации, выполнение которых занимает 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?

Спасибо, Имон

Ответы [ 6 ]

310 голосов
/ 30 марта 2011
  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. Отслеживание прогресса (необязательно, но часто полезно)

    а) подписаться на ProgressChanged событие и использовать ReportProgress(Int32) в DoWork

    b) установить worker.WorkerReportsProgress = true; (кредиты @zagy)

35 голосов
/ 02 июня 2014

Возможно, вы захотите также использовать Task вместо фоновых рабочих.

Самый простой способ сделать это в вашем примере - Task.Run(InitializationThread);.

Есть несколько преимуществ использования заданий вместо фоновых работников. Например, новые функции async / await в .net 4.5 используют Task для многопоточности. Вот некоторая документация о Task http://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx

13 голосов
/ 31 мая 2015
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 /

5 голосов
/ 14 июля 2011

В дополнение к тому, что сказал Эндрю Орсич, может быть, вы хотите прочитать несколько примеров об этом.

Вот пример кода с использованием фонового рабочего и индикатора выполнения

http://devtoolshed.com/content/c-download-file-progress-bar

и вот небольшой учебник

http://www.dotnetperls.com/backgroundworker

и в конце урока есть ссылка на еще один пример прогресса + фонового работника.

3 голосов
/ 24 сентября 2013

Я нашел это ( Многопоточность WPF: использование BackgroundWorker и Отчет о ходе выполнения в пользовательском интерфейсе. Ссылка ), чтобы содержать остальные детали, которые отсутствуют в ответе Эндрю.

Одна вещь, которую я нашел очень полезной, состояла в том, что рабочий поток не мог получить доступ к элементам управления MainWindow (в своем собственном методе), однако при использовании делегата внутри обработчика событий главного окна это было возможно.

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;
};
1 голос
/ 30 марта 2011

Попробуйте эту ссылку Класс BackgroundWorker в MSDN , который содержит пример того, как его использовать.

...