異なるホストのさまざまなディレクトリから1つのディレクトリに多数のファイルをコピーしようとしています。それは非常に時間がかかることが判明し、このプログラムを何度も実行しなければならないので、各スレッドがプロセスを通じてXCOPYを実行するマルチスレッドの助けを借りてコードを変更しました。複数のスレッド生成プロセスが同じディレクトリにファイルをコピーするときのファイルエントリが見つかりませんC#
しかし、私はマルチスレッドコピーを行っているときに、いくつかのファイル(100未満、毎回変化する)がコピーされないことを知りました。私は同じディレクトリにXCOPYingするときに複数のプロセスが介在しているのか、XCOPYの問題であるのか(同じ宛先で複数プロセスの呼び出しをどれくらいうまくサポートしているかは不明です)
List<Thread> threadList = new List<Thread>;
foreach(FileEntry fileEntry in fileEntries)
{
Thread thread = new Thread(() => {
//full path of file, like \\host\directory\directoryB\fileA.txt
string filePath = fileEntry._filePath;
//name of file, like fileA.txt
string file = fileEntry._file;
//dumpDirectory is where I want to copy all the files to
string destPath = Path.Combine(dumpDirectory, file);
//each file here is either a directory or a real file, bad naming convention I know...(open to suggestions if any)
string fileType = File.Exists(filePath) ? "f" : "d";
using (Process process = new Process())
{
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = string.Format(@"/C echo {0} | XCOPY /E /C /H /R /K /O /Y {1} {2}", fileType, filePath, destPath);
Console.WriteLine("copying {2} [{0}] to destination [{1}]", filePath, destPath, string.Compare(fileType, "f") == 0 ? "file" : "directory");
process.Start();
process.WaitForExit();
if (process.ExitCode != 0)
{
Console.WriteLine("encountered problems when copying file [{0}]", filePath);
}
}
});
thread.Start();
threadList.Add(thread);
}
foreach(Thread thread in threadList)
{
thread.Join();
}
---------------------------次のようなバグ修正------------ -------------------
私の週末を保存したので、以下の返信(クイック返信のおかげで^ _ ^)のように、プロセスの出力をリダイレクトしました問題が「共有違反\ nディレクトリを作成できません」であることが判明しました。 xcopyは、複数のファイルを同じディレクトリにコピーするときに問題があります(さまざまなxcopyプロセスは、ディレクトリがシステム上に存在しないことをすべて検出すると同時にディレクトリを作成するように見えます)。 Parallel.Foreachに手動でスレッド管理を変更する
が問題を解決し、
か(私はなぜそれが同じ問題を作成していない考え出したていないが)、コードが見やすく作られた、汚れた修正がラップすることですEventWaitHandleでprocess.Start()を起動します。私は他の方法は、まず第一に、マルチプロセス
//name the wait handle based on destination value
EventWaitHandle destWaitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, string.Format("waitHandle{0}", destPath.GetHashCode()));
//only trigger the wait handle lock if the file being copied from (and to) is a directory. Based on the error log info XCopy seemed to never have issues with copying individual files
//and the program worked fine if I only put the lock at directory level
if (string.Compare(fileType, "d") == 0)
{
destWaitHandle.WaitOne();
}
process.Start();
//this line was added to write error messages into respective files during the process' execution
process.BeginErrorReadLine();
process.WaitForExit();
if (string.Compare(fileType, "d") == 0)
{
destWaitHandle.Set();
}
おそらくあなたはProcess.StartからStandardOutputを示すことができた...何かが私は、Dが –
が起こっています上のコメントに直接返信する方法はわかりませんが、私はちょっと助けてくれてありがとうございます。提案したように、私は出力全体をリダイレクト/ダンプし、問題がどこにあるかを知りました。 –
マルチスレッディングを使用してファイルをコピーするのは、ごくわずかです。あなたがCPUに束縛された操作を持っているなら、スレッドは有益です。 IOでは、CPUは事実上アイドル状態です。実際には、マルチスレッドIOはハードドライブ競合を導入し、**コピープロセスでエラー**を引き起こす可能性があるため、コピーを遅くする**ことができます。 – Enigmativity