【发布时间】:2016-07-05 09:18:17
【问题描述】:
我有以下代码注册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++ api 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 执行得更好。
另外(或除此之外),我想知道是否有比以下方法更好的方法让应用程序在后台运行(没有 UI):
while (true)
{
System.Threading.Thread.Sleep(10000);
}
我觉得这可能不是保持应用程序打开的最佳方式,但我不确定。
有人能给点建议吗?
【问题讨论】:
-
FileSystemWatcherALREADY usesReadDirectoryChanges,因此您不太可能通过自己动手来改进。 -
在 .NET Core 1.0 的开发过程中,微软确实发现了该领域的多个性能问题。您将不得不等到他们将它们登陆 .NET Framework,或者您现在就开发一个 .NET Core 1.0 RTM 应用程序。
-
@MatthewWatson 如果微软确实在这个类中存在错误,这不是 100% 正确的。
-
@LexLi 很有趣 - 你有关于这个的链接吗?
-
@MatthewWatson 我在 GitHub 的糟糕搜索中找不到旧项目,但这个新项目看起来也很有趣,github.com/dotnet/corefx/issues/8059
标签: c# c++ filesystemwatcher