2010-10-04 12 views
5

Ich habe eine C# -Konsolenanwendung, die einige Threads hat, um etwas Arbeit zu erledigen (Datei herunterladen). Jeder Thread kann die Anwendung zu jeder Zeit wo in der Anwendung beenden, aber ich werde eine ordnungsgemäße Nachricht auf der Konsole zeigen. Es ist möglich, sie zu verfolgen, aber für mich ergibt das keinen Sinn. Ich möchte einfach die Anzahl der Threads überprüfen, um herauszufinden, welcher der letzte Thread ist und was passiert, wenn der Thread beendet wird. Was ist die beste Vorgehensweise, um dies zu tun?Letzter Thread einer Multithread-Anwendung

Pseudocode:

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

Dank

+1

Welche Version von C#/.NET verwenden Sie? –

+0

Ich kann jede Version verwenden – Xaqron

Antwort

11

Dies ist ein Ort, an dem die neue Task Parallel-Bibliothek verwendet, kann das Leben viel einfacher machen. Statt dessen Fäden zu schaffen, und auf den Faden Aufarbeiten Spinnen, können Sie mehrere Aufgaben verwenden:

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 

Wenn die „Aufgaben“ sind nur ein paar einzelne Dateien herunterzuladen, können Sie auch diese einfacher mit PLINQ machen:

var fileUrls = GetListOfUrlsToDownload(); 

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

cleanUp(); // Do your cleanup 
+0

+1 unter der Annahme, dass sie .NET 4.0 verwenden. –

+0

+1 für einfachere Feuer-und-Vergessen-Lösung –

+1

@Mark: Ich nehme nicht an, dass sie sind - aber wenn sie nicht sind, möchte ich Motivation zum Verschieben bieten;) –

1

Ihr Haupt-Thread sollte join mit allen Arbeitsthreads und Block, während sie ausgeführt werden. Wenn dann alle Threads abgeschlossen sind, führt es den Bereinigungscode aus und wird dann beendet.

Alternativ können Sie eine WaitHandle wie zB eine ManualResetEvent pro Thread und wait for all von ihnen signalisieren.

+0

Es gibt viele verschiedene Orte, wo Threads den Code verlassen. Es ist schwer, sie irgendwo zurück zu bringen und ihnen beizutreten – Xaqron

2

Ein Design, bei dem Sie den Überblick über Ihre Gewinde verlieren, ist nicht ideal.

Je nachdem, wie Sie sie spawnen, sollte es möglich sein, den Status von jedem zu verfolgen, indem Sie ein signalfähiges Objekt pro Thread zuordnen und dann WaitAll auf diese signalisierbaren Objekte.

Jedes signalisierbare Objekt sollte seinerseits signalisiert werden, wenn der Thread beendet wird. Wenn sie alle signalisiert werden, weißt du, dass die Fäden alle tot sind und du sauber machst. Sie müssen sicherstellen, dass abnormale Bedingungen in Ihren Threads nicht dazu führen, dass das zugeordnete signalisierbare Objekt des Threads nicht festgelegt wird, oder Ihr WaitAll wird nie zurückkehren. Dies bedeutet normalerweise Ausnahmen - könnte try...finally verwenden, um sicherzustellen, dass die Objekte signalisiert werden.

Ihr neuer Pseudo-Code ist

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

WaitAll for all events to be signalled 
cleanup