Mam trochę kodu, który muszę uruchomić w innym wątku niż GUI, ponieważ obecnie powoduje zawieszanie się formularza podczas działania kodu (około 10 sekund).
Załóżmy, że nigdy wcześniej nie tworzyłem nowego wątku; jaki jest prosty / podstawowy przykład tego, jak to zrobić w języku C # i przy użyciu .NET Framework 2.0 lub nowszej?
c#
.net
multithreading
p.campbell
źródło
źródło
Odpowiedzi:
Dobrym miejscem do rozpoczęcia czytania jest Joe Albahari .
Jeśli chcesz utworzyć własny wątek, jest to tak proste, jak to możliwe:
źródło
IsBackground
true. Prawdopodobnie nie działa tak, jak myślisz. To, co robi, to konfigurowanie, czy wątek zostanie zabity, gdy wszystkie wątki pierwszego planu zginą, czy też wątek utrzyma aplikację przy życiu. Jeśli nie chcesz, aby Twój wątek zakończył się w trakcie wykonywania, nie ustawiaj wartościIsBackground
true.BackgroundWorker
wydaje się być najlepszym wyborem dla Ciebie.Oto mój minimalny przykład. Po kliknięciu przycisku pracownik w tle rozpocznie pracę w wątku w tle i jednocześnie będzie raportować swoje postępy. Będzie także raportować po zakończeniu pracy.
Uwaga:
ProgressChanged
lub w programieRunWorkerCompleted
obsługi jest bezpieczne . Jednak aktualizacja GUIDoWork
spowodujeInvalidOperationException
.źródło
ThreadPool.QueueUserWorkItem jest całkiem idealne do czegoś prostego. Jedynym zastrzeżeniem jest dostęp do kontrolki z drugiego wątku.
źródło
Szybki i brudny, ale zadziała:
U góry:
prosty kod:
Właśnie wrzuciłem to do nowej aplikacji konsolowej na przykład
źródło
Oto kolejna opcja:
źródło
Spróbuj użyć klasy BackgroundWorker . Dajesz mu delegatów do uruchomienia i powiadamiania o zakończeniu pracy. Na stronie MSDN znajduje się przykład, z którym się łączyłem.
źródło
Jeśli chcesz uzyskać wartość:
źródło
Umieść ten kod w funkcji (kod, którego nie można wykonać w tym samym wątku co GUI), a aby uruchomić wykonanie tego kodu, wstaw następujące polecenie.
Thread myThread= new Thread(nameOfFunction);
workerThread.Start();
Wywołanie funkcji start na obiekcie wątku spowoduje wykonanie wywołania funkcji w nowym wątku.
źródło
nameOfFunction
w tle, a nie w bieżącym wątku GUI.IsBackground
Właściwość określa, czy wątek będzie utrzymywać aplikację żyje czy nie: msdn.microsoft.com/en-us/library/...Tutaj, jak używać wątków z paskiem postępu, służy to po prostu zrozumieniu działania wątków, w formie są trzy paski postępu i przycisk 4:
źródło
Charles twój kod (powyżej) jest niepoprawny. Nie musisz obracać się, czekając na zakończenie. EndInvoke będzie blokować do momentu zasygnalizowania WaitHandle.
Jeśli chcesz zablokować do czasu zakończenia, po prostu musisz
lub alternatywnie
Ale jaki jest sens wydawania połączeń anyc, jeśli blokujesz? Równie dobrze możesz użyć połączenia synchronicznego. Lepszym rozwiązaniem byłoby nie blokowanie i przekazywanie lambda do czyszczenia:
Należy pamiętać, że musisz wywołać EndInvoke. Wiele osób zapomina o tym i w końcu wyciekają WaitHandle, ponieważ większość implementacji asynchronicznych zwalnia waithandle w EndInvoke.
źródło
Jeśli zamierzasz użyć surowego obiektu Thread, musisz ustawić IsBackground na minimum, a także powinieneś ustawić model Threading Apartment (prawdopodobnie STA).
Poleciłbym klasę BackgroundWorker, jeśli potrzebujesz interakcji z interfejsem użytkownika.
źródło
inna opcja, która wykorzystuje delegatów i pulę wątków ...
zakładając, że „GetEnergyUsage” jest metodą, która przyjmuje DateTime i inną DateTime jako argumenty wejściowe i zwraca Int ...
źródło
int usageCnt = nrgDel.Invoke(lastRunTime, procDT, null, null);
? Wygląda na to, że i tak wstrzymuje bieżący wątek podczas snu ... Myślałem, że nic nie pomoże w zawieszeniu GUI, jeśli wywołasz go w wątku GUIIstnieje wiele sposobów uruchamiania osobnych wątków w .Net, z których każdy ma inne zachowania. Czy musisz kontynuować uruchamianie wątku po zamknięciu GUI? Czy potrzebujesz przekazać informacje między wątkiem a GUI? Czy wątek wymaga aktualizacji GUI? Czy wątek powinien wykonać jedno zadanie, a następnie zakończyć, czy powinien nadal działać? Odpowiedzi na te pytania podpowiedzą, jakiej metody użyć.
W witrynie Code Project znajduje się dobry artykuł na temat metody asynchronicznej, który opisuje różne metody i podaje przykładowy kod.
Uwaga: ten artykuł został napisany przed wprowadzeniem wzorca asynchronicznego / oczekiwania i biblioteki zadań równoległych do .NET.
źródło
Instrukcje: używanie wątku w tle do wyszukiwania plików
Musisz być bardzo ostrożny z dostępem z innych wątków do specyficznych dla GUI rzeczy (jest to powszechne w wielu zestawach narzędzi GUI). Jeśli chcesz zaktualizować coś w GUI z przetwarzania wątku, sprawdź tę odpowiedź, która moim zdaniem jest przydatna dla WinForm. W przypadku WPF zobacz to (pokazuje, jak dotknąć komponentu w metodzie UpdateProgress (), aby działał z innych wątków, ale tak naprawdę nie podoba mi się, że nie robi się to
CheckAccess()
przedBeginInvoke
przejściem przez Dispathcer, zobacz i wyszukaj w nim CheckAccess)Szukałem konkretnej książki .NET na temat wątków i znalazłem tę (do pobrania za darmo). Więcej informacji na ten temat można znaleźć na stronie http://www.albahari.com/threading/ .
Wierzę, że znajdziesz to, czego potrzebujesz, aby uruchomić wykonywanie jako nowy wątek na pierwszych 20 stronach i ma on o wiele więcej (nie jestem pewien co do fragmentów specyficznych dla GUI, to znaczy ściśle specyficznych dla wątków). Z przyjemnością usłyszę, co społeczność myśli o tej pracy, ponieważ ją czytam. Na razie wyglądało to dla mnie całkiem fajnie (do pokazywania metod i typów specyficznych dla .NET dla wątków). Obejmuje również .NET 2.0 (a nie starożytny 1.1), co naprawdę doceniam.
źródło
Poleciłbym przejrzeć bibliotekę Power Threading Library Jeffa Richtera, a zwłaszcza IAsyncEnumerator. Spójrz na wideo na blogu Charliego Calvert'a, na którym Richter je omawia, aby uzyskać dobry przegląd.
Nie zniechęcaj się tą nazwą, ponieważ ułatwia kodowanie zadań programowania asynchronicznego.
źródło