Тест, показывающий, что FileSystemWatcher работает неправильноC#

Место общения программистов C#
Ответить
Anonymous
 Тест, показывающий, что FileSystemWatcher работает неправильно

Сообщение Anonymous »

Работая над устаревшей базой кода, я наткнулся на следующий код в OnCreated обработчике событий для FileSystemWatcher:

Код: Выделить всё

        string directoryPathToWatch = ConfigurationManager.AppSettings["PathFile"]; // Path to directory that is being watched for newly created '.txt' files

private void fileSystemWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
Thread.Sleep(300000);

DirectoryInfo di = new DirectoryInfo(directoryPathToWatch);
FileSystemInfo[] files = di.GetFileSystemInfos("*.txt");
var dir = files.OrderBy(f => f.Name);

foreach (var file in dir)
{
// processes each file and after it is done, moves it to Output folder . . .
}
}
Я подозреваю, что следующий код неверен, потому что операция Thread.Sleep(300000) ожидает создания нескольких файлов для их обработки. в порядке, определяемом именем файла (например, 0001.txt, 0002.txt и т. д.).
Насколько я понимаю, код также неверен, поскольку для каждый новый создан файл .txt в каталоге, создается новое событие Create event, которое обрабатывается в новом потоке(

Код: Выделить всё

fileSystemWatcher_Created
метод). При раскручивании 1-го потока для первого созданного файла он начинает обработку всех файлов, которые найдены в каталоге, а при запуске последующих потоков (для 2-го, 3-го, 4-го и т.д. файлов) ) выполняются, они попытаются обработать файлы, которые могли быть перемещены 1-м потоком и больше не существуют в каталоге.
Я попробовал создать новые файлы почти одновременно, используя несколько потоков, используя Барьер, но испытание пройдено.

Код: Выделить всё

readonly string OUT_FOLDER_PATH = "D:\\path_to_directory_where_windows_service_Outputs_processed_files";

[Test]
public void Test_fsw_fails()
{
string sampleDataFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SampleData"); // folder where sample data is located

string[] inputDataFileNames = Enumerable.Range(0, 59)
.Select(n => $"{n.ToString("0000")}.txt")
.ToArray();

using (Process applicationProcess = new Process()
{
StartInfo = new ProcessStartInfo("D:\\path_to_windows_service_executable.exe")
{
CreateNoWindow = false
}
})
{
applicationProcess.Start();
Barrier moveInputDataBarrier = new Barrier(59);

Task[] moveInputDataTasks = Enumerable.Range(0, 59)
.Select(n => new Task(() =>
{
string localSampleDataFolderPath = sampleDataFolderPath;
string localFileName = inputDataFileNames[n];
int localN = n;

moveInputDataBarrier.SignalAndWait();

File.Copy(Path.Combine(localSampleDataFolderPath, localFileName), Path.Combine(OUT_FOLDER_PATH, localFileName));
}))
.ToArray();

applicationProcess.Kill();
}

Assert.That(Directory.EnumerateFiles(OUT_FOLDER_PATH).Count(), Is.EqualTo(59)); // Correct number of files processed

foreach (var actualOutputFileFullPath in Directory.EnumerateFiles(OUT_FOLDER_PATH, "*.txt"))
{
byte[] actualOutputFileContent = File.ReadAllBytes(actualOutputFileFullPath);
byte[] expectedOutputFileContent = File.ReadAllBytes(Path.Combine(sampleDataFolderPath, Path.GetFileName(actualOutputFileFullPath)));

Assert.That(actualOutputFileContent, Is.EquivalentTo(expectedOutputFileContent)); // Check for content equality
}
}
Поиск ответов в Stackoverflow Я наткнулся на несколько предложений, в которых люди советуют избегать FileSystemWatcher, поскольку он ненадежен и следует использовать другие методы интеграции. Обработка папки с несколькими файлами с использованием FileSystemWatcher и C#. Какие еще методы следует рассматривать в качестве альтернативы, если это возможно?

Подробнее здесь: https://stackoverflow.com/questions/793 ... ncorrectly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»