2017-05-24 5 views
-5

Ich habe eine Anwendung, die ich ausgewählt habe, um Thread. Die Absicht dahinter ist, mehrere Threads gleichzeitig auszuführen, um die Anwendung zu beschleunigen.C# Thread Async-Verarbeitung

Derzeit ich die Anwendungseinstellungen Schleife, Erstellen eines Threads für jede Einstellung, dann starten Sie jede, und beitreten, damit ich sagen kann, wenn sie alle abgeschlossen sind.

Leider wird dabei jeder Thread synchron ausgeführt, was den Zweck vereitelt.

Ich könnte es ändern, um den Join zu entfernen, aber dann kann ich nicht feststellen, wann alle Threads fertig sind (ich muss dies tun, als wenn sie alle fertig sind, habe ich einen einzigen Prozess zu laufen).

Ich fange an zu denken, Threading ist nicht für mich, aber das sollte ich mehr auf die threading.tasks oder die parallel.foreach, aber ich bin unsicher, die Komplexität von diesen beiden. Ich habe weder Mechanismus vor (und auch nur dabbled mit Gewinde)

unten ist ein Codeausschnitt verwendet, die zur Zeit meine Themen

foreach (SettingsProperty value in Properties.Settings.Default.Properties) 
{ 
    //parse out the line in the settings 
    if (value.Name.ToString() != <<criteria>>) 
    { 
     //this is one that we want to do something with 
     sett = value.DefaultValue.ToString().Split(stringSeparators, StringSplitOptions.None); 

     //set the directory 
     Directory.CreateDirectory(<<directory>>); 

     //fire the thread to retrieve the image form the url 
     ThreadWithState tws = new ThreadWithState(<<parameters>>); 
     Thread t = new Thread(new ThreadStart(tws.ThreadProc)); 
     t.Start(); 
     t.Join(); 

    } 
} 
UploadFiles(); 

Derzeit wird diese führt die Fäden nacheinander und führt dann den letzten Prozess laicht . Wenn ich den Aufruf von t.join entferne, werden die Threads asynchron ausgeführt, aber auch der Upload wird ausgeführt, bevor alle Threads abgeschlossen sind.

Wie kann ich entweder den Code ändern zu warten, bis alle Threads zu beenden, oder implementieren die Parallel.ForEach (was ich denke, kann arbeiten, aber haben kein Verständnis) oder einige threading.tasks implementieren funktionieren so I können Sie die Task.WhenAll Methode (was ich denke, auch arbeiten können, aber haben kein Verständnis)

+1

Warum rufen Sie 't.Join()'? –

+1

Ihre Frage ist zu breit. Es gibt viele gültige Möglichkeiten, um Dinge gleichzeitig auszuführen. Ihr Code versucht keine dieser Möglichkeiten. Durch sofortiges Aufrufen von 'Join()' in dem Thread, den Sie gerade gestartet haben, starten Sie keinen anderen Thread, bis der aktuelle fertig ist. Wenn du nicht warten willst, bevor du einen anderen Thread startest, ** dann warte nicht **. –

+4

Sie sagen, Sie wissen, was das richtige Werkzeug ist - erstellen Sie einen asynchronen Workflow - und dass Sie nicht wissen, wie es geht. Also * lerne wie es geht *. Dies ist keine Tutorial-Site. Es gibt viele Tutorials zu parallelen und asynchronen Workflows. Geh und hol dir eins! Für IO-gebundene Aufgaben wie diese würde ich zunächst etwas über asynchrone Workflows lernen. Sie müssen nicht mehrere Threads einbeziehen. –

Antwort

0

Thread.Join() weist den ausführenden Thread (wait), bis der andere Thread beendet seine Aufgabe zu blockieren.

Also das

t.Start(); 
t.Join(); 

bedeutet wörtlich die Aufgabe starten und nichts tun, bis es fertig ist.

Wenn Sie Parallel.ForEach verwenden möchten, könnten Sie damit beginnen, die Liste zu erstellen, auf der Sie arbeiten möchten. Zum Beispiel

var properties = Properties.Settings.Default.Properties 
    .Where(property => Name != "whatever"); 

Jetzt properties ist eine IEnumerable<SettingsProperty> - eine Kollektion, die aufgezählt werden kann, oder durchgeschleift.

Jetzt können Sie dies tun:

Parallel.ForEach(properties, (property) => 
    { 
     // do something with the property. 
    }); 

Dies ist im Wesentlichen die gleiche wie

foreach(var property in properties) 
{ 
    // do something with the property. 
} 

außer dass die Iterationen der Schleife kann laufen auf gleichzeitige Threads. "Mai", weil der Aufgabenplaner Threads verwendet, die der Arbeitslast und den verfügbaren Ressourcen entsprechen.

-3

Sie möchten mehrere Bilder gleichzeitig von einem Webserver herunterladen?

Ich würde alle Threads gleichzeitig starten (Was Sie gerade tun, aber ohne die thread.join()), und legen Sie sie alle in einer Liste, wie Sie sie machen. Nach Ihrer foreach (vor UploadFiles()) durchlaufen Sie die Liste ständig, bis alle Threads gestoppt haben. Dies hat den Effekt, dass die Ausführung blockiert wird, bis alle Aufgaben erledigt sind, anstatt die Ausführung zu blockieren, bis Ihre aktuelle Aufgabe/der Download abgeschlossen ist.

bool stillRunning = true; 
while(stillRunning) 
    stillRunning = false; 
    foreach(Thread thr in threadList) 
     if(thr.IsAlive) 
      stillRunning = true; 

UploadFiles(); 
+1

Das ist * schrecklicher * Rat und du solltest es nicht tun. Erstens: Warum sollten Sie IO-gebundene Arbeit einem Worker-Thread zuweisen? All diese Arbeit kann mit * einem * Thread erledigt werden. Zweitens, wenn Sie mehreren Threads Arbeit zuweisen wollten, dann verwenden Sie die parallele Bibliothek der Aufgabe und lassen Sie sie zuweisen, herausfinden, wann sie abgeschlossen ist, und so weiter. Drittens: * Abfrage der Threads nicht, um zu sehen, ob sie erledigt sind *. Dies ist ein modernes Multi-Thread-Betriebssystem; Wenn Sie auf den Abschluss vieler Threads warten möchten, gibt es viele * korrekte * Mechanismen. –

+0

Danke für das Feedback Eric, ich erkenne, dass dies bei weitem nicht eine optimale Lösung ist und dass man _die verschiedenen Bibliotheken und Sprachfunktionen verwenden sollte. Aber ich gehöre auch zu dem Gedankengang, der mir sagt, dass das, was am schnellsten oder am einfachsten zu codieren ist, in manchen Situationen am besten funktioniert. Welche "richtigen" Mechanismen gibt es, um zu bestimmen, wann eine Anzahl von Threads fertig ist, die besser sind, als sie einfach wiederholbar abzufragen? Da ich nicht viel über alternative Methoden weiß, habe ich geantwortet, wie man seinen Code ändert, damit er nicht blockiert, wie gefragt. Es gibt viele Lösungen für ein Problem. – TheWhoAreYouPerson

+1

Korrekte Analyse von Programmen mit * multiplen Threads der Kontrolle * - Programme, die * schwer zu analysieren * und für * Milliarden * an Produktivitätsverlust verantwortlich sind, sind genau jene Programme, die * niemals * von Amateuren, die ' Ich verstehe die Grundlagen und mache alles, was am schnellsten zu programmieren ist *. Wenn das deine Einstellung zur Programmierung ist, gibt es viele, viele Arten von Programmieraufgaben, bei denen diese Einstellung profitabel ist. Multi-threaded Kontrollfluss ist nachdrücklich nicht einer von ihnen. –