Вопрос по performance, .net, filesystemwatcher, c# – Это действительно так дорого, чтобы увеличить FileSystemWatcher.InternalBufferSize?

10

м, используяFileSystemWatcher отслеживать изменения в папке, но как только у меня есть несколько сотен изменений за короткое время, я пропускаю некоторые из них, потому что переполнен внутренний буфер. Поэтому я хочу увеличитьInternalBufferSize (Я знаю, что выигралдействительно не решит проблему, но это уменьшит вероятность ее возникновения), но я вижу это предупреждение вдокументация:

Тем не менее, увеличение размера буфера дорого,потому что он исходит из невыгружаемой памяти, которая не может быть выгружена на дисктак что держите буфер как можно меньше.

Итак, мой вопрос: это действительно имеет значение? Большинство компьютеров сегодня имеют по крайней мере 1 ГБ ОЗУ, поэтому мне кажется, что если я установлю размер буфера в 1 МБ (вместо 8 КБ по умолчанию), это не должноне имеет значения, может ли 1 МБбыть выгруженным на диск. Или я что-то упустил? Я неЯ не знаю много о вещах низкого уровня, таких как выгружаемая / невыгружаемая память, поэтому яя не уверен, какое влияние это окажет ...

@StuartDunkeld, да, но я думаю, чтоЭто просто рекомендация. В коде нет ничего, что могло бы обеспечить его соблюдение, и оно работает, если вы установите значение больше 64 КБ. Thomas Levesque
Документы также говорят "Вы можете установить буфер на 4 КБ или больше, нооно не должно превышать 64 КБ. " stuartd
@ SteveWellens, да, и я сказал так же в своем вопросе. Однако это сделает неизбежное менее вероятным ... Thomas Levesque
Если события происходят быстрее, чем вы можете их обработать, увеличение размера буфера задержит неизбежное. Steve Wellens
@ThomasLevesque - я неНе знаю, поможет ли это вам, но когда я отслеживал каталог для входящих файлов, я выключал наблюдатель, обрабатывал все файлы в каталоге, пока он не был пустым, а затем снова включал наблюдатель. Steve Wellens

Ваш Ответ

3   ответа
3

Рассмотрим дизайн потребительского производителя для чтения в событиях FileSystemWatcher.

Обзор BlockingCollection

Если у вас есть некоторые события FileSystemWatcher, вы нене нужно обрабатывать, а затем быстро уволить их.

Или, если некоторые могут обрабатывать быстрее, чем другие имеют отдельную коллекцию, чтобы уменьшить общий счет.

Спасибо япопробую! Thomas Levesque
3

Объем невыгружаемой памяти ограничен (обновление: современные версии Windows неОн имеет такой же строгий предел, как и в предыдущих версиях, и объем памяти теперь является гибким значением, которое зависит от общего объема оперативной памяти, доступной для Windows) и очень важно для жителей режима ядра (драйверов устройств, самой ОС). Потребление этого без строгого контроля может быстро вызвать нестабильность в системе, и, что еще хуже, вы выиграли »не найти, что вызвало эту нестабильность.

Кроме того, как показывают комментарии, этоВажен не размер буфера, а скорость удаления данных из буфера.

В большинстве случаев драйвер фильтра файловой системы будет работать лучше, чем FileSystemWatcher. Преимущества состоят в том, что вы можете иметь любой буфер журнала, который вам нужен (как вы бы создали его в любой памяти, которая вам нужна, и не ограничиваться не выгружаемой памятью), а также вы можете обрабатывать события по мере их возникновения, а не после того, как они происходят. Кроме того, вы можете фильтровать запросы с более высокой степенью детализации, чем позволяет FileSystemWatcher.

Спасибо за Ваш ответ. Я'Я читал о драйверах фильтров файловой системы, но яЯ бы не хотел идти по этому пути, по крайней мере, сейчас. Попытка удалить события из буфера быстрее, вероятно, мой лучший вариант Thomas Levesque
18

Память, в которой выделяется буфер, безусловно, является ценным ресурсом. Windows не справится с исчерпанием пула памяти, драйверы начнут выходить из строя случайно. Размер пула задается динамически (но может быть изменен) и зависит от объема доступной оперативной памяти.

Размер буфера по умолчанию, который запрашивает FSW, составляет 8192 байта. Не много на современных машинах. Основная функция winapi не позволит вам запрашивать более 64 КБ. Запись в буфере составляет 12 байт плюс длина пути к файлу, умноженная на два. В худшем случае 8192 / (12 + 260 * 2) = 15 уведомлений до того, как закончится буфер. В большинстве случаев это должно работать без особых проблем, если только вы не отслеживаете весь диск или у вас очень высокий трафик диска в каталоге, который вы просматриваете. В этом случае справедливо запросить больший буфер. Не существует золотой формулы, обязательно реализуйте событие FileSystemWatcher.Error, чтобы вызнать что тыу нас проблема с буфером.

В большинстве практических случаев вам нужно внимательно относиться к событиям ЖСБ. Они будут вызваны, пока у процесса все еще есть блокировка файла. Так что делать такие вещи, как открытие или копирование файла, хлопотно. Вы справляетесь с этим, помещая уведомления в потокобезопасную очередь и используете другой поток, чтобы попытаться получить блокировку для файла, несколько раз, если это необходимо. Такая очередь теперь автоматически также является очень хорошим способом быстрой очистки буфера. Единственное, что высейчас надо следить за тем, чтобы очередь нене может выйти за пределы разумных масштабов, которые приведут к аварийному завершению вашей программы с помощью OOM.

Да. Он использует замки, вы можетене вижу их. Он оптимизирован для минимальных накладных расходов на блокировку. Hans Passant
Может ли это работать с использованием ConcurrentQueue или что-то подобное? Я думаю, что это неиспользовать замки или нет? Я мог бы просто поставить в очередь события и обработать их в другом потоке. Thomas Levesque
Спасибо за этот подробный ответ. В большинстве случаев я неМне действительно нужен большой буфер, но я заметил, что если пользователь копирует большой каталог в каталог, яя смотрю, яЯ получаю переполнения буфера, которые заставляют меня пропустить некоторые события. Хорошее решение - очистить буфер как можно быстрее. В настоящее время у меня естьlock в обработчике событий, вероятно, поэтому яне достаточно быстро очищать буфер; Я'Попробую сделать это без блокировки, чтобы улучшить производительность. Thomas Levesque
Осторожно, это неЭто легко сделать без блокировки. События генерируются в потоке потоков, поэтому блокировка почти всегда требуется. Hans Passant

Похожие вопросы