当多个文件同时添加到目录时,FileSystemWatcher 无法正常工作...
Watcher 根本无法找到目录中的所有文件 - 仅当文件被一一放置在文件夹中时 - 如果大量文件同时复制到文件夹中,则不会......
线程的创建是解决问题的方法还是有另一种方法来处理问题?
当多个文件同时添加到目录时,FileSystemWatcher 无法正常工作...
Watcher 根本无法找到目录中的所有文件 - 仅当文件被一一放置在文件夹中时 - 如果大量文件同时复制到文件夹中,则不会......
线程的创建是解决问题的方法还是有另一种方法来处理问题?
该类的文档详细说明了该问题:
Windows 操作系统会通知您的组件有关 FileSystemWatcher 创建的缓冲区中的文件更改。如果短时间内有很多变化,缓冲区可能会溢出。这会导致组件失去对目录更改的跟踪,并且它只会提供一揽子通知。使用InternalBufferSize属性增加缓冲区的大小是昂贵的,因为它来自无法换出到磁盘的非分页内存,因此请保持缓冲区小而大,以免错过任何文件更改事件。要避免缓冲区溢出,请使用NotifyFilter和IncludeSubdirectories属性,以便您可以过滤掉不需要的更改通知。
因此,在这种情况下,线程可能对您没有太大帮助。您可能想要增加缓冲区大小(但它应该有多大可能取决于计算机和磁盘本身的速度)或通过设置适当的过滤器来限制您感兴趣的文件。
C# 对我来说是新手,我为同样的问题苦苦挣扎了将近一周。我有这个:
private void btnWatchFile_Click(object sender, EventArgs e)
{
//code to create a watcher and allow it to reise events...
}
//watcher onCreate event
public void onCreated(object sender, FileSystemEventArgs e)
{
if (!updateNotifications )
{
stringBuilder.Remove(0, stringBuilder.Length);
stringBuilder.Append(e.FullPath);
stringBuilder.Append(" ");
stringBuilder.Append(e.ChangeType.ToString());
stringBuilder.Append(" ");
stringBuilder.Append(DateTime.Now.ToString());
updateNotifications = true;
}
}
//timer to check the flag every X time
private void timer_Tick(object sender, EventArgs e)
{
if (updateNotifications )
{
notificationListBox.Items.Insert(0, stringBuilder.ToString());
updateNotifications = false;
}
}
我什至将计时器间隔设置为 1 毫秒,但仍然缺少一些新的文件事件。我试图notificationsListBox
从onCreated
事件内部更新,但总是出现交叉引用错误。直到我发现观察者onCreated
事件是在主方法线程之外的线程中执行的,所以,简而言之,这是我的解决方案:
我将public delegate void Action()
其作为类的属性包含在内,然后用于从事件内部Invoke
更新。接下来,片断代码:notificationsListBox
onCreated
public void onCreated(object sender, FileSystemEventArgs e)
{
stringBuilder.Remove(0, stringBuilder.Length);
stringBuilder.Append(e.FullPath);
stringBuilder.Append(" ");
stringBuilder.Append(e.ChangeType.ToString());
stringBuilder.Append(" ");
stringBuilder.Append(DateTime.Now.ToString());
updateNotifications = true;
Invoke((Action)(() => {notificationListBox.Items.Insert(0, stringBuilder.ToString());}));
}
因此不再需要计时器及其代码。这对我来说非常有用,我希望它适用于任何有类似情况的人。此致!!!
try something like this.
public MainWindow()
{
InitializeComponent();
#region initialise FileSystemWatcher
FileSystemWatcher watch = new FileSystemWatcher();
watch.Path = folder;
watch.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
watch.Filter = ext;
watch.Changed += new FileSystemEventHandler(OnChanged);
watch.Created += new FileSystemEventHandler(OnChanged);
watch.EnableRaisingEvents = true;
#endregion
}
private void OnChanged(object source, FileSystemEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke((Action)delegate
{
// do your work here. If this work needs more time than it can be processed, not the filesystembuffer overflows but your application will block. In this case try to improve performance here.
}, System.Windows.Threading.DispatcherPriority.Normal);
}