2017-03-22 1 views
4

ich die unten Routine bin mit einer Gruppe von Videos aus einem Verzeichnis zu verarbeiten:Wie multi-threading mein Code mehrere Dateien gleichzeitig zu verarbeiten, durch die gleiche Funktion?

AllVideos = new List<MyVideo>(); 

for (int i = 0; i < AllVideosFileNames.Length; i++) 
{ 
    MyVideo CurrentVid = new MyVideo(AllVideosFileNames[i], false); // constructor (loads the video to the system) 
    CurrentVid.PopulateAllFrames(); // Method that takes forever 
    CurrentVid.PopluateTestFrames(); // Method that takes less than forever 
    CurrentVid.NormalizeTestFrames(); // Method that takes some time 
    AllVideos.Add(CurrentVid); // Add finished object to my results container 
} 

Ich mag mehrere Videos gleichzeitig verarbeiten, parallel dazu, und Zeit sparen. Ich habe versucht, dies zu tun:

for (int i = 0; i < AllVideosFileNames.Length; i++) 
{ 
    Thread TempThread = new Thread(() => 
    { 
     MyVideo CurrentVid = new MyVideo(AllVideosFileNames[i], false); 
     CurrentVid.PopulateAllFrames(); 
     CurrentVid.PopluateTestFrames(); 
     CurrentVid.NormalizeTestFrames(); 
     AllVideos.Add(CurrentVid); 
    }); 
    TempThread.Start(); 
} 

Allerdings führt dies so schnell und tut buchstäblich nichts. Mit nichts meine ich, wenn ich durch den Code gehe, AllVideos ist leer, wenn die Schleife beendet wird.

Irgendwelche Ideen für ein besseres Design? oder eine Reparatur? Bitte und danke.

+2

Versuchen Sie es mit/Lern ​​TPL, die mehr besser ist, und Sie haben controll über Ihre Aufgaben. [Siehe this] (https://msdn.microsoft.com/en-us/library/dd460717 (v = vs.110) .aspx) –

+0

Wenn Sie nur einen Thread für jede Arbeit starten, wird der übergeordnete Thread einfach fortgesetzt. Sie müssen warten, bis sie fertig sind. Ich würde stattdessen lieber eine Aufgabe für jeden erstellen (mit 'Task.Run'), dann eine' Task.Wait' für die erstellten Aufgaben, nachdem sie erstellt wurden. Dann werden sie parallel zur Fertigstellung laufen – Baldrick

+0

Wie lange dauert es in der normalen Schleife für 1 Iteration? Es sieht so aus, als würden Ihre Threads nach Beendigung der Schleife schwellen. Was ist mit 'AllVideos''? Woher kommt das? Sie können Race-Condition-Probleme haben, wenn es sich nicht um eine lokale Variable handelt. Betrachten Sie Sperren –

Antwort

3

Vielleicht in TPL und/oder PLINQ. Wissen Sie über ?

Wie wäre:

AllVideos = AllVideosFileNames 
    .AsParallel() 
    .Select(fileName => GetVideo(filename)) 
    .ToList(); 

Wo GetVideo(filename) wie folgt definiert ist:

private MyVideo GetVideo(string filename) 
{ 
    MyVideo currentVid = new MyVideo(filename, false); 
    currentVid.PopulateAllFrames(); 
    currentVid.PopluateTestFrames(); 
    currentVid.NormalizeTestFrames(); 
    return currentVid; 
} 

Introduction to PLINQ für weitere Informationen.

+2

'AllVideosFileNames [i]' sollte 'filename' sein –

+2

@MatiasCicero Danke, dass du das erwischt hast! Es ist jetzt behoben. – PJvG

+0

Hallo und danke. Gibt es eine Möglichkeit zu wissen, wann die Verarbeitung für alle Dateien abgeschlossen ist? (Nein, ich weiß nichts über 'AsParallel', aber es sieht fantastisch aus) –

3

Sie könnten versuchen, Parallel.ForEach zu verwenden. Es wird warten, bis der letzte Thread seine Ausführung, bevor Sie fortfahren beendet ist:

Parallel.ForEach(AllVideosFileNames, item => 
{ 
    MyVideo CurrentVid = new MyVideo(item, false); 
    CurrentVid.PopulateAllFrames(); 
    CurrentVid.PopluateTestFrames(); 
    CurrentVid.NormalizeTestFrames(); 
    AllVideos.Add(CurrentVid); 

}); 

Haftungsausschluss:

Wie bereits erwähnt und wieder von Dmitry Bychenko zu Aufmerksamkeit brachte die ListAllVideos speichern nicht Thema ist. Vielleicht möchten Sie Sperren in Betracht ziehen:

Parallel.ForEach(AllVideosFileNames, item => 
{ 
    MyVideo CurrentVid = new MyVideo(item, false); 
    CurrentVid.PopulateAllFrames(); 
    CurrentVid.PopluateTestFrames(); 
    CurrentVid.NormalizeTestFrames(); 
    lock (AllVideos) 
    { 
     AllVideos.Add(CurrentVid); 
    }  
}); 
+0

Ich denke, dass ich damit gehe, da es standardmäßig darauf wartet, dass der letzte Thread beendet wird. Awesome fix danke Mong –

+0

Gern geschehen. –

+2

'AllVideos' ist eine' Liste 'ist ** nicht ** threadsicher; deshalb können Sie Probleme mit 'AllVideos.Add (CurrentVid) haben;' –

Verwandte Themen