ファイルが作成されたときに Created イベントを受け取ります (名前の由来)。しかし、この時点で、実際にそれを作成している他のプロセスは、そのファイルへのコンテンツの書き込みを完了していません。したがって、ファイルは既にそこにある可能性がありますが、他のファイルはまだ作業中です (8 GB のファイルをコピーするとします)。
ファイルのパスをイベント内のリストに単純に書き込み、別のスレッドがこの並行バッグを定期的に (たとえば 1 秒に 1 回) チェックするようにする方が賢明です。まず、ファイルが存在するかどうかを確認し、存在する場合は削除を試みます。成功した場合はバッグから取り出し、失敗した場合は次回に再試行します。
コード例
private static readonly ConcurrentQueue<FileInfo> _FileCandidates = new ConcurrentQueue<FileInfo>();
private static void Main(string[] args)
{
var watcher = new FileSystemWatcher
{
Path = @"R:\TestFolder",
IncludeSubdirectories = false,
Filter = "*.*",
};
Console.WriteLine("Start watching folder... " + watcher.Path);
watcher.Created += OnFileCreated;
watcher.EnableRaisingEvents = true;
var timer = new Timer
{
AutoReset = true,
Interval = 1000,
};
timer.Elapsed += OnTimerElapsed;
timer.Enabled = true;
Console.ReadKey();
}
static void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
FileInfo file;
var stillInUseFiles = new List<FileInfo>();
Console.WriteLine("Check for file candidates...");
while (_FileCandidates.TryDequeue(out file))
{
try
{
Console.WriteLine("Delete " + file.FullName);
if (file.Exists)
file.Delete();
}
catch (IOException)
{
Console.WriteLine("Could not delete file, try again next time.");
stillInUseFiles.Add(file);
}
}
foreach (var unhappyFile in stillInUseFiles)
{
_FileCandidates.Enqueue(unhappyFile);
}
}
static void OnFileCreated(object sender, FileSystemEventArgs e)
{
Console.WriteLine("Found new file candidate " + e.FullPath);
_FileCandidates.Enqueue(new FileInfo(e.FullPath));
}