#c# #multithreading #io #file-copying
#c# #многопоточность #io #копирование файла
Вопрос:
У меня проблема с многопоточностью при копировании и доступе к файлам.
У меня есть служба, которая загружает и распаковывает Zip-архив, затем копирует файл из распакованной папки в нужное место:
//Download, and uzip archive...
//Copy a needed file to its right location
File.Copy(fileName, fileDestination);
Затем я запускаю отдельный поток, который должен получить доступ к скопированным файлам:
TheadPool.QueueUserWorkItem(s => processCopiedFile(fileDestination));
Вот фрагмент кода из ProcessCopiedFile:
private void ProcessCopiedFile(string filePath)
{
...
//Load the file, previously copied here
var xml = XDocument.Load(filePath);
...
//Do other work...
}
XDoument.Сбой вызова Load с исключением:
The process cannot access the file <FileName> because it is used by another process.
Похоже на файл.Копирование сохраняет файл результата заблокированным. Когда все работают синхронно, он работает без ошибок.
У вас есть какие-либо мысли?
Спасибо.
Ответ №1:
Файл.Копирование ничего не сохраняет открытым или заблокированным, это атомарная операция, которая требует некоторого времени, в зависимости, конечно, от дискового / сетевого ввода / вывода и размера файла.
Конечно, при переходе от синхронизации к асинхронности вы должны убедиться, что вы не обращаетесь к файлу назначения, пока копирование все еще выполняется.
Комментарии:
1. Сначала я вызываю File . Скопируйте (синхронно), затем я запускаю новый поток. Вызвать файл. Копирование вызывается синхронно, оно гарантированно завершает свою работу до запуска нового потока. Или я где-то ошибаюсь?
2. 1 — Просто для пояснения последней части: Windows сохраняет эксклюзивную блокировку файла во время его копирования.
Ответ №2:
Скопируйте файл с потоком, чтобы избежать блокировки Windows из File.Copy
using(var s = new MemoryStream(File.ReadAllBytes(filePath))
{
using(var fs = new FileStream(newLocation, FileMode.Create))
{
s.WriteTo(fs);
}
}
Комментарии:
1. Правильное копирование файлов — это ракетостроение. Необходимо позаботиться о сохранении атрибутов файла и альтернативных потоков в файле. Не делайте этого самостоятельно.