Как использовать фоновый рабочий стол 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
?
Ответы
Ответ 1
- Добавить с помощью
using System.ComponentModel;
- Объявите фонового работника:
private readonly BackgroundWorker worker = new BackgroundWorker();
- Подписаться на события:
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
- Реализуйте два метода:
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
}
- Запускайте рабочий асинхронизатор всякий раз, когда вам нужно.
worker.RunWorkerAsync();
Отслеживать прогресс (необязательно, но часто полезно)
а) подписаться на событие ProgressChanged
и использовать ReportProgress(Int32)
в DoWork
б) установить worker.WorkerReportsProgress = true;
(кредиты @zagy)
Ответ 2
Вы можете также захотеть использовать Task
вместо фоновых работников.
Самый простой способ сделать это в вашем примере - Task.Run(InitializationThread);
.
Есть несколько преимуществ использования задач вместо фоновых работников. Например, новые функции async/await в .net 4.5 используют Task
для многопоточности. Вот некоторая документация по Task
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task
Ответ 3
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/
Ответ 4
в дополнение к тому, что сказал Эндрю Орсич, возможно, вы хотите прочитать несколько примеров об этом.
вот пример кода с использованием фона рабочего и progressbar
http://devtoolshed.com/content/c-download-file-progress-bar
и вот небольшой учебник
http://www.dotnetperls.com/backgroundworker
и есть ссылка для другого примера progressbar + backgroundworker в конце учебника.
Ответ 5
Я нашел это (многопоточность WPF: использование BackgroundWorker и отчет о прогрессе в интерфейсе пользователя), чтобы содержать остальные детали, которые отсутствуют из ответа @Andrew.
Единственное, что мне показалось очень полезным, это то, что рабочий поток не смог получить доступ к элементам 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;
};
Ответ 6
Попробуйте эту ссылку BackgroundWorker Class в MS Docs, которая содержит пример того, как его использовать.