Сценарий, в котором у меня есть 10 000 XML-файлов, которые я хочу прочитать и сохранить в базе данных. У меня есть 5 служб Windows, которые все попадают в папку, чтобы попытаться обработать.C# File Move (Rename) Multi Thread Windows OS
Моя техника - это сначала попробовать и переименовать (File.Move) файл с расширением, специфичным для данного Сервисного экземпляра.
Это работает в 99% случаев. Однако то, что я вижу, это файловая система. 0,01% времени позволяют двум запросам попробовать и переименовать ТОЧНО в то же время.
Как я могу предотвратить это? Имеет ли это смысл? См. Следующий фрагмент кода, чтобы получить представление. В итоге у меня около 10 файлов, которые являются исключениями ввода-вывода.
string[] sourceFiles = Directory.GetFiles(InputPath, string.Format(LocaleHelper.Culture, "*.{0}", Extention))
.OrderBy(d => new FileInfo(d).CreationTime).ToArray();
foreach (string file in sourceFiles)
{
var newFileName = string.Format(LocaleHelper.Culture, "{0}.{1}", file, CacheFlushManager.GetInstanceName);
try
{
// first we'll rename // however at this point the file may not even exist
// it will throw an exception and move onto the next file if it exists
File.Move(file, newFileName);
var xml = File.ReadAllText(newFileName);
// write to DB at this point we know its unique
}
catch (FileNotFoundException ex)
{
Logger.LogDebug(string.Format(LocaleHelper.Culture, "{0} Couldn't read file : {1}", CacheFlushManager.GetInstanceName, newFileName));
}
catch (IOException ex)
{
Logger.LogDebug(string.Format(LocaleHelper.Culture, "{0} Couldn't process file : {1}", CacheFlushManager.GetInstanceName, newFileName));
}
catch (Exception ex)
{
Logger.LogError("Execute: Error", ex);
try
{
File.Move(newFileName, string.Format(LocaleHelper.Culture, "{0}.badfile", newFileName));
}
catch (Exception ex_deep)
{
Logger.LogError(string.Format("{0} Execute: Error Deep could not move bad file {1}", CacheFlushManager.GetInstanceName, newFileName), ex_deep);
}
}
EDIT 1
Ниже точная ошибка в качестве примера того, что я вижу. Я очень смущен тем, как файл действует, что точное время может быть использовано на основе кода, который я использую? Неужели я полностью из этого сорняка?
[7220] TransactionFileServiceProcess [11:28:32]: Service4 не удалось обработать файл: C: \ Temp \ Input \ yap804.xml.Service4 System.IO.IOException: Процесс не может получить доступ к файлу ' C: \ temp \ Input \ yap804.xml.Service4 ', потому что он используется другим процессом.
EDIT 2
Вот посмотрите на то, что происходит с «отладки» точки зрения. Как оба сервиса 2 & 3 попадают в «END RENAME?»? Я думаю, что это суть проблемы ... мысли?
Проблема в файле yap620.xml.Service3
в конечном итоге будет просто сидеть там из-за ошибки операции с файлом.
[6708] TransactionFileServiceProcess [10:54:38]: Service3 Start Rename: C:\temp\Input\yap620.xml.Service3 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
[4956] TransactionFileServiceProcess [10:54:38]: Service2 Start Rename: C:\temp\Input\yap620.xml.Service2 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
[7416] TransactionFileServiceProcess [10:54:38]: Service4 Start Rename: C:\temp\Input\yap620.xml.Service4 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
[6708] TransactionFileServiceProcess [10:54:38]: Service3 End Rename: C:\temp\Input\yap620.xml.Service3 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
[6708] TransactionFileServiceProcess [10:54:38]: Service3 Start Read: C:\temp\Input\yap620.xml.Service3 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
[4956] TransactionFileServiceProcess [10:54:38]: Service2 End Rename: C:\temp\Input\yap620.xml.Service2 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
[4956] TransactionFileServiceProcess [10:54:38]: Service2 Start Read: C:\temp\Input\yap620.xml.Service2 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
[6708] TransactionFileServiceProcess [10:54:38]: Service3 Couldn't process file : C:\temp \Input\yap620.xml.Service3 TransactionFileServiceProcess.Execute => BHSLogger.LogDebug => LoggerImpl.Write E[]
10 000 XML-файлов? почему бы не использовать JSON? – thenewseattle
У меня нет выбора, к какому файловому формату они относятся, к сожалению. И в этом случае это не имело бы значения. – aherrick
Попытка устранить столкновение не имеет смысла - у вас, похоже, уже достаточно кода, чтобы избежать этого - так что просто ожидайте, что столкновения (или любые другие ошибки ввода-вывода) произойдут и повторите попытку. –