-
FileSystemWatcher
触发多次
Change
事件的解决办法
p>
最近要用到
FileSystemWatcher
< br>来监控某个目录中的文
件是否发生改变,如果改变就执行相应的操作。但在开发过
程中,
发现
FileSystemWa
tcher
在文件创建或修改后,
会触发
多个
Created
或
Change
d
事件,具体原因就是处理文件的过
程中执行了多次文件系统操
作,触发了多次事件。具体可以
参看微软的关于
FileSys
temWatcher
这方面的解释:
Troubleshoo
ting FileSystemWatcher Components
,
另外我在网
上发现
Consolidate Multiple FileSystemWatcher
Events
关于
这方面的解决办法,比较实用,方便快速引
入到项目中。
来自
MSDN
的问题说明
Troubleshooting FileSystemWatcher
Components
Visual Studio
.NET 2003
其他版本此主题尚未评级
-
评价此主题
You may encounter
the following situations while working
with the
FileSystemWatcher component:
UNC Path Names Not Accepted on Windows
NT 4.0 Computers
If you are working
with a FileSystemWatcher component on a
Windows NT version 4.0 computer and
trying to set its path to
monitor file
system activity on a different Windows NT version
4.0 computer, you will not be able to
specify a UNC-based path
value in the
Path property to point to the computer in
question.
You can only set UNC-based
values when working on Windows
2000
computers.
Cannot Watch Windows 95 or
Windows 98 Directories
If you set your
FileSystemWatcher component to reference a
directory on a Windows 95 or Windows 98
computer, you will
receive an error
about an invalid directory path when the project
runs. When using FileSystemWatcher, you
cannot watch
directories on computers
running Windows 95 or Windows 98.
Multiple Created Events Generated for a
Single Action
You may notice in certain
situations that a single creation event
generates multiple Created events that
are handled by your
component. For
example, if you use aFileSystemWatcher
component to monitor the creation of
new files in a directory,
and then test
it by using Notepad to create a file, you may see
two Created events generated even
though only a single file was
created.
This is because Notepad performs multiple file
system
actions during the writing
process. Notepad writes to the disk in
batches that create the content of the
file and then the file
attributes.
Other applications may perform in the same manner.
Because FileSystemWatcher monitors the
operating system
activities, all events
that these applications fire will be picked
up.
Note
Notepad may also cause
other interesting event
generations.
For example, if you use the ChangeEventFilter to
specify that you want to watch only for
attribute changes, and
then you write
to a file in the directory you are watching using
Notepad, you will raise an event . This
is because Notepad
updates theArchived
attribute for the file during this operation.
Unexpected Events Generated on
Directories
Changing a file within a
directory you are monitoring with a
FileSystemWatcher component generates
not only a Changed
event on the file
but also a similar event for the directory itself.
This is because the directory maintains
several types of
information for each
file it contains
—
the names
and sizes of
files, their modification
dates, attributes, and so on. Whenever
one of these attributes changes, a
change is associated with the
directory
as well.
解决方案
The .NET
framework provides a FileSystemWatcher class that
can be used to monitor the file system
for changes. My
requirements were to
monitor a directory for new files or
changes to existing files. When a
change occurs, the application
needs to
read the file and immediately perform some
operation
based on the contents of the
file.
While doing some manual testing
of my initial implementation
it was
very obvious that theFileSystemWatcher was firing
multiple events whenever I made a
change to a file or copied a
file into
the directory being monitored. I came across the
following in the MSDNdocumentation’s
Troubleshooting
FileSystemWatcher
Components
Multiple Created
Events Generated for a Single Action
You may notice in certain situations
that a single creation event
generates
multiple Created events that are handled by your
component. For example, if you use a
FileSystemWatcher
component to monitor
the creation of new files in a directory,
and then test it by using Notepad to
create a file, you may see
two Created
events generated even though only a single file
was
created. This is because Notepad
performs multiple file system
actions
during the writing process. Notepad writes to the
disk in
batches that create the content
of the file and then the file
attributes. Other applications may
perform in the same manner.
Because
FileSystemWatcher monitors the operating system
activities, all events that these
applications fire will be picked
up.
Note: Notepad may also cause other
interesting event
generations. For
example, if you use the ChangeEventFilter to
specify that you want to watch only for
attribute changes, and
then you write
to a file in the directory you are watching using
Notepad, you will raise an event. This
is because Notepad
updates the Archived
attribute for the file during this operation.
I did some searching and
was surprised that .NET did not
provide
any kind of wrapper around the FileSystemWatcher
to
make it a bit more user friendly. I
ended up writing my own
wrapper that
would monitor a directory and only throw one
event when a new file was created, or
an existing file was
changed.
In order to consolidate the multiple
FileSystemWatcher events
down to a
single event, I save the timestamp when each event
is
received, and I check back every so
often (using a Timer) to find
paths
that have not caused additional events in a while.
When
one of these paths is ready, a
single Changed event is fired. An
additional benefit of this technique is
that the event from the
FileSystemWatcher is handled very
quickly, which could help
prevent its
internal buffer from filling up.
Here
is the code for a DirectoryMonitor class that
consolidates
multiple Win32 events into
a single Change event for each
change:
解决方案代码
[csharp] view
plaincopyprint?
using System;
using c;
using
using
using
using ing;
namespace ShareReadFile
{
public delegate void
FileSystemEvent(String path);
public interface IDirectoryMonitor
{
event FileSystemEvent
Change;
void Start();
}
public class
DirectoryMonitor : IDirectoryMonitor
{
private readonly FileSystemWatcher
m_fileSystemWatcher = new
FileSystemWatcher();
private readonly Dictionary<string,
DateTime>
m_pendingEvents = new
Dictionary<string, DateTime>();
private readonly Timer
m_timer;
private bool m_timerStarted = false;
public
DirectoryMonitor(string dirPath)
{
m_ = dirPath;
m_eSubdirectories =
false;
m_d += new
FileSystemEventHandler(OnChange);
m_d += new
FileSystemEventHandler(OnChange);
m_timer = new
Timer(OnTimeout, null,
te, te);
}
public event FileSystemEvent Change;
public void Start()
{
m_RaisingEvents =
true;
}
private void
OnChange(object sender,
FileSystemEventArgs e)
{
// Don't want other threads messing
with the
pending events right now
lock (m_pendingEvents)
{
// Save a timestamp for the most recent
event for this path
m_pendingEvents[th] =
;
// Start a timer if not
already started
if (!m_timerStarted)
{
m_(100, 100);
m_timerStarted = true;
}
}
}
private void
OnTimeout(object state)
{
List<string> paths;
-
-
-
-
-
-
-
-
-
上一篇:ANE Scratch Live 软件参数设置中文说明
下一篇:ncbi中文说明书