Улучшение производительности FileSystemWatcher

У меня есть следующий код, который регистрирует FileSystemWatcher а затем запускает какой-то метод DoRequiedWork() Всякий раз, когда происходит событие записи в указанном файле. Существует также некоторая логика, чтобы предотвратить запуск нескольких событий при каждой записи (с lastRead а также lastWriteTime):

// To prevent multiple events from firing
static DateTime lastRead = DateTime.MinValue;
static string UserName = GetUserName();

private static void Run()
{
// Create a new FileSystemWatcher and set its properties.
var watcher = new FileSystemWatcher
{
Path = $@"\\file\home$\{UserName}\Application Data",
NotifyFilter =
NotifyFilters.LastWrite,
Filter = "filetowatch.txt"};

// Activate
watcher.Changed += OnChanged;
watcher.EnableRaisingEvents = true;

while (true)
{
System.Threading.Thread.Sleep(10000);
}
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
var lastWriteTime = File.GetLastWriteTime(e.FullPath);

if (lastWriteTime == lastRead) return;

DoRequiredWork();

lastRead = lastWriteTime;
}

Я хотел бы реализовать это с помощью c++ апи ReadDirectoryChangesW в попытке улучшить производительность, но я не уверен, как это сделать.

Я проверил PInvoke, и можно увидеть, что подпись может быть определена как:

[DllImport("kernel32.dll")]
static extern bool ReadDirectoryChangesW(IntPtr hDirectory, IntPtr lpBuffer,
uint nBufferLength, bool bWatchSubtree, uint dwNotifyFilter, out uint
lpBytesReturned, IntPtr lpOverlapped,
ReadDirectoryChangesDelegate lpCompletionRoutine);

Я хотел бы начать с того, как создать это, но сначала хотел проверить, действительно ли это будет работать лучше, чем стандартный управляемый c # FileSystemWatcher,

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

while (true)
{
System.Threading.Thread.Sleep(10000);
}

Как мне кажется, это не лучший способ держать приложение открытым, но я не уверен.

Кто-нибудь может посоветовать?

-1

Решение

Похоже, что вы держитесь за поток в вашем методе Run. Не делай этого. Вместо этого держите статическую ссылку вокруг. Похоже, вы смотрите сетевую долю. Не ожидайте высокой производительности, так как это касается не только дисковой подсистемы, но и сетевой подсистемы (на вашей стороне и на сервере). Существует слишком много факторов, чтобы ожидать, что использование одного и того же API-интерфейса внезапно приведет к огромному увеличению производительности.

static FileSystemWatcher watcher;

private static void Run()
{
// Create a new FileSystemWatcher and set its properties.
// if you're watching a network share, don't expect huge performance
// as the network is involved
watcher = new FileSystemWatcher
{
Path = $@"\\file\home$\{UserName}\Application Data",
NotifyFilter =
NotifyFilters.LastWrite,
Filter = "filetowatch.txt"};

// Activate
watcher.Changed += OnChanged;
watcher.EnableRaisingEvents = true;

AppDomain.CurrentDomain.DomainUnload += (s,e) => {
var w = watcher as IDisposable;
if (w != null) w.Dispose();
};
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]