W mojej aplikacji muszę wykonać serię czynności inicjalizacyjnych, których ukończenie zajmuje 7-8 sekund, podczas których mój interfejs użytkownika przestaje odpowiadać. Aby rozwiązać ten problem, wykonuję inicjalizację w osobnym wątku:
public void Initialization()
{
Thread initThread = new Thread(new ThreadStart(InitializationThread));
initThread.Start();
}
public void InitializationThread()
{
outputMessage("Initializing...");
//DO INITIALIZATION
outputMessage("Initialization Complete");
}
Przeczytałem kilka artykułów o tym, BackgroundWorker
jak i jak powinno to pozwolić mi zachować responsywność mojej aplikacji bez konieczności pisania wątku w celu wykonania długich zadań, ale nie odniosłem żadnego sukcesu, próbując go wdrożyć, czy ktoś mógłby powiedzieć, jak bym to zrobił to za pomocą BackgroundWorker
?
c#
wpf
multithreading
backgroundworker
Eamonn McEvoy
źródło
źródło
Odpowiedzi:
Śledź postępy (opcjonalne, ale często przydatne)
a) zapisać się na
ProgressChanged
wydarzenie i używaćReportProgress(Int32)
wDoWork
b) zestaw
worker.WorkerReportsProgress = true;
(kredyty do @zagy)źródło
Możesz również przyjrzeć się używaniu
Task
zamiast pracowników w tle.Najłatwiej to zrobić na twoim przykładzie
Task.Run(InitializationThread);
.Korzystanie z zadań zamiast pracowników w tle ma kilka zalet. Na przykład nowe funkcje async / await w .net 4.5 służą
Task
do obsługi wątków. Oto dokumentacja dotyczącaTask
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskźródło
BackgroundWorker
. Mając nadzieję, że uda mi się do tego nakierować ludzi.async
iawait
. Są to zintegrowane językowo sposoby korzystania z zadań w znacznie bardziej czytelny sposób.Skorzystaj również z poniższego łącza, aby zrozumieć pojęcia
Background
:http://www.c-sharpcorner.com/UploadFile/1c8574/threads-in-wpf/
źródło
Okazało się, że to ( WPF Multithreading: Using the BackgroundWorker and Reporting the Progress to the UI link. ) Zawiera pozostałe szczegóły, których brakuje w odpowiedzi @ Andrew.
Jedyną rzeczą, która okazała się bardzo przydatna, było to, że wątek roboczy nie mógł uzyskać dostępu do kontrolek MainWindow (w swojej własnej metodzie), jednak podczas używania delegata wewnątrz procedury obsługi zdarzeń głównego okna było to możliwe.
źródło