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.
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: Ссылка
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.
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.
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:
Tags und Links c# parallel-processing copyfile