File.Copy in Parallel.ForEach

8

Ich versuche ein Verzeichnis zu erstellen und kopiere eine Datei (pdf) in ein Parallel.ForEach .

Unten ist ein einfaches Beispiel:

%Vor%

Die obige Methode erstellt einen neuen Ordner und kopiert die PDF-Datei in einen neuen Ordner. Es erstellt diesen Verzeichnisbaum:

%Vor%

Ich habe versucht, die Methode CreateFolderAndCopyFile in einer Parallel.ForEach Schleife aufzurufen.

%Vor%

Wenn ich diesen Code ausführe, wird der folgende Fehler angezeigt:

  

Der Prozess kann nicht auf die Datei 'c: \ testdata \ Data00001102 \ test.pdf' zugreifen.   weil es von einem anderen Prozess verwendet wird.

Aber zuerst hat es 1111 neue Ordner erstellt und test.pdf etwa 1111 Mal kopiert, bevor ich diesen Fehler bekam.

Was hat dieses Verhalten verursacht und wie kann es behoben werden?

EDITED:

Code oben war Spielzeugbeispiel, Entschuldigung für hart codierte Zeichenfolgen Fazit: Parallele Methode ist langsam.

Morgen probiere ich einige Methoden aus Wie schreibe ich super-schneller Datei-Streaming-Code in C #? .

besonders: Ссылка

    
Mike 28.03.2012, 18:07
quelle

2 Antworten

18

Sie synchronisieren nicht den Zugriff auf index und das bedeutet, dass Sie ein Rennen haben. Deshalb haben Sie den Fehler. Zur Veranschaulichung können Sie das Rennen vermeiden und dieses spezielle Design beibehalten, indem Sie Interlocked.Increment verwenden.

%Vor%

Wie jedoch andere vermuten, ist die alternative Überladung von ForEach eine Schleife Index ist eindeutig eine sauberere Lösung für dieses spezielle Problem.

Aber wenn Sie es zum Laufen bringen, werden Sie feststellen, dass das Kopieren von Dateien IO-gebunden und nicht prozessorgebunden ist, und ich sage voraus, dass der parallele Code langsamer ist als der serielle Code.

    
David Heffernan 28.03.2012, 18:09
quelle
6

Ihre inkrementelle Operation in index ist dahingehend verdächtig, dass sie nicht threadsicher ist. Wenn Sie die Operation in Console.WriteLine("{0}", index++) ändern, wird dieses Verhalten angezeigt.

Stattdessen könnten Sie eine Parallel.ForEach Überladung mit einem Schleifenindex verwenden:

%Vor%     
user7116 28.03.2012 18:12
quelle