2010-10-04 21 views
5

Mam aplikację konsoli C#, która ma kilka wątków do wykonania pracy (pobierz plik). każdy wątek może wyjść z aplikacji w dowolnym momencie w dowolnym miejscu w aplikacji, ale pokażę odpowiedni komunikat na konsoli. Można je śledzić, ale nie ma to dla mnie żadnego sensu. Chcę po prostu sprawdzić liczbę wątków lub coś w tym stylu, aby dowiedzieć się, który z nich jest ostatnim wątkiem i zrobić coś podczas wychodzenia. Jaka jest najlepsza praktyka, aby to zrobić?Ostatni wątek aplikacji wielowątkowej

pseudokod:

if (lastThread) 
{ 
    cleanUp(); 
    Console.ReadLine(); 
} 

Dzięki

+1

Jakiej wersji C#/.NET używasz? –

+0

Mogę użyć dowolnej wersji – Xaqron

Odpowiedz

11

Jest to jedno miejsce, w którym za pomocą Task Parallel Library nowy może uczynić życie znacznie łatwiejsze. Zamiast tworzyć wątki i przędzenie pracować na wątku, można korzystać z wielu zadań:

var task1 = Task.Factory.StartNew(() => DoTaskOneWork()); 
var task2 = Task.Factory.StartNew(() => DoTaskTwoWork()); 
var task3 = Task.Factory.StartNew(() => DoTaskThreeWork()); 

// Block until all tasks are done 

Task.WaitAll(new[] {task1, task2, task3}); 
cleanUp(); // Do your cleanup 

Jeśli „Zadania” są po prostu pobierając kilka pojedynczych plików, można nawet zrobić to prostsze przy użyciu PLINQ:

var fileUrls = GetListOfUrlsToDownload(); 

fileUrls.AsParallel().ForAll(fileUrl => DownloadAndProcessFile(fileUrl)); 

cleanUp(); // Do your cleanup 
+0

+1 przy założeniu, że używają .NET 4.0. –

+0

+1 dla prostszego rozwiązania polegającego na braku ognia i zapomnienia –

+1

@ Mark: Nie zakładam, że są - ale jeśli nie, chcę zapewnić motywację do poruszania się;) –

1

Twój główny wątek powinien join ze wszystkich wątków roboczych i bloku, gdy są uruchomione. Następnie, gdy wszystkie wątki są kompletne, wykonuje kod oczyszczania, a następnie kończy działanie.

Alternatywnie można użyć WaitHandle, takich jak ManualResetEvent na wątek i wait for all z nich do sygnalizowania.

+0

Istnieje wiele różnych miejsc, w których wątki opuszczają kod. Ciężko je przywrócić i dołączyć do nich – Xaqron

2

Projekt, w którym tracisz kontrolę nad wątkami, nie jest idealny.

W zależności od tego, jak je odradzamy, powinno być możliwe śledzenie stanu każdego z nich, poprzez powiązanie z obiektem pewnych podlegających sygnalizacji obiektów, a następnie WaitAll tych sygnalizowanych obiektów.

Każdy sygnał dźwiękowy z kolei powinien zostać zasygnalizowany w momencie wyjścia wątku. Kiedy wszystkie są sygnalizowane, wiesz, że nici są martwe, a ty zamykasz w czystości. Musisz upewnić się, że nienormalne warunki w twoich wątkach nie powodują, że powiązany sygnał podlegający temu wątkowi pozostanie niezasilony, lub Twój WaitAll nigdy nie wróci. Oznacza to zazwyczaj wyjątki - można użyć try...finally, aby zapewnić zasygnalizowanie obiektów.

Twój nowy pseudokod jest

foreach (workitem in list of work) 
    start up thread associated with a ManualResetEvent or similar 

WaitAll for all events to be signalled 
cleanup 
Powiązane problemy