4
4
5
5
namespace FileWatcherEx ;
6
6
7
+ /// <summary>
8
+ /// A wrapper of <see cref="FileSystemWatcher"/> to standardize the events
9
+ /// and avoid false change notifications.
10
+ /// </summary>
7
11
public class FileSystemWatcherEx : IDisposable
8
12
{
9
13
10
14
#region Private Properties
11
15
12
- private Thread _thread ;
13
- private EventProcessor _processor ;
14
- private BlockingCollection < FileChangedEvent > _fileEventQueue = new ( ) ;
16
+ private Thread ? _thread ;
17
+ private EventProcessor ? _processor ;
18
+ private readonly BlockingCollection < FileChangedEvent > _fileEventQueue = new ( ) ;
15
19
16
- private FileWatcher _watcher = new ( ) ;
17
- private FileSystemWatcher _fsw = new ( ) ;
20
+ private FileWatcher ? _watcher ;
21
+ private FileSystemWatcher ? _fsw ;
18
22
19
23
// Define the cancellation token.
20
- private CancellationTokenSource _cancelSource = new ( ) ;
24
+ private readonly CancellationTokenSource _cancelSource = new ( ) ;
21
25
22
26
#endregion
23
27
@@ -26,26 +30,23 @@ public class FileSystemWatcherEx : IDisposable
26
30
#region Public Properties
27
31
28
32
/// <summary>
29
- /// Folder path to watch
33
+ /// Gets or sets the path of the directory to watch.
30
34
/// </summary>
31
35
public string FolderPath { get ; set ; } = "" ;
32
36
33
37
34
38
/// <summary>
35
- /// The collection of all the filters used to determine what files are monitored in a directory.
39
+ /// Gets the collection of all the filters used to determine what files are monitored in a directory.
36
40
/// </summary>
37
41
public System . Collections . ObjectModel . Collection < string > Filters { get ; } = new ( ) ;
38
42
39
43
40
44
/// <summary>
41
- /// Filter string used for determining what files are monitored in a directory
45
+ /// Gets or sets the filter string used to determine what files are monitored in a directory.
42
46
/// </summary>
43
47
public string Filter
44
48
{
45
- get
46
- {
47
- return Filters . Count == 0 ? "*" : Filters [ 0 ] ;
48
- }
49
+ get => Filters . Count == 0 ? "*" : Filters [ 0 ] ;
49
50
set
50
51
{
51
52
Filters . Clear ( ) ;
@@ -55,7 +56,11 @@ public string Filter
55
56
56
57
57
58
/// <summary>
58
- /// Gets, sets the type of changes to watch for
59
+ /// Gets or sets the type of changes to watch for.
60
+ /// The default is the bitwise OR combination of
61
+ /// <see cref="NotifyFilters.LastWrite"/>,
62
+ /// <see cref="NotifyFilters.FileName"/>,
63
+ /// and <see cref="NotifyFilters.DirectoryName"/>.
59
64
/// </summary>
60
65
public NotifyFilters NotifyFilter { get ; set ; } = NotifyFilters . LastWrite | NotifyFilters . FileName | NotifyFilters . DirectoryName ;
61
66
@@ -69,38 +74,64 @@ public string Filter
69
74
/// <summary>
70
75
/// Gets or sets the object used to marshal the event handler calls issued as a result of a directory change.
71
76
/// </summary>
72
- public ISynchronizeInvoke SynchronizingObject { get ; set ; }
77
+ public ISynchronizeInvoke ? SynchronizingObject { get ; set ; }
73
78
74
79
#endregion
75
80
76
81
77
82
78
83
#region Public Events
79
- public delegate void DelegateOnChanged ( object sender , FileChangedEvent e ) ;
80
- public event DelegateOnChanged OnChanged ;
81
84
82
- public delegate void DelegateOnDeleted ( object sender , FileChangedEvent e ) ;
83
- public event DelegateOnDeleted OnDeleted ;
85
+ /// <summary>
86
+ /// Occurs when a file or directory in the specified
87
+ /// <see cref="FolderPath"/> is changed.
88
+ /// </summary>
89
+ public event DelegateOnChanged ? OnChanged ;
90
+ public delegate void DelegateOnChanged ( object ? sender , FileChangedEvent e ) ;
91
+
92
+
93
+ /// <summary>
94
+ /// Occurs when a file or directory in the specified
95
+ /// <see cref="FolderPath"/> is deleted.
96
+ /// </summary>
97
+ public event DelegateOnDeleted ? OnDeleted ;
98
+ public delegate void DelegateOnDeleted ( object ? sender , FileChangedEvent e ) ;
84
99
85
- public delegate void DelegateOnCreated ( object sender , FileChangedEvent e ) ;
86
- public event DelegateOnCreated OnCreated ;
87
100
88
- public delegate void DelegateOnRenamed ( object sender , FileChangedEvent e ) ;
89
- public event DelegateOnRenamed OnRenamed ;
101
+ /// <summary>
102
+ /// Occurs when a file or directory in the specified
103
+ /// <see cref="FolderPath"/> is created.
104
+ /// </summary>
105
+ public event DelegateOnCreated ? OnCreated ;
106
+ public delegate void DelegateOnCreated ( object ? sender , FileChangedEvent e ) ;
107
+
108
+
109
+ /// <summary>
110
+ /// Occurs when a file or directory in the specified
111
+ /// <see cref="FolderPath"/> is renamed.
112
+ /// </summary>
113
+ public event DelegateOnRenamed ? OnRenamed ;
114
+ public delegate void DelegateOnRenamed ( object ? sender , FileChangedEvent e ) ;
115
+
116
+
117
+ /// <summary>
118
+ /// Occurs when the instance of <see cref="FileSystemWatcherEx"/> is unable to continue
119
+ /// monitoring changes or when the internal buffer overflows.
120
+ /// </summary>
121
+ public event DelegateOnError ? OnError ;
122
+ public delegate void DelegateOnError ( object ? sender , ErrorEventArgs e ) ;
90
123
91
- public delegate void DelegateOnError ( object sender , ErrorEventArgs e ) ;
92
- public event DelegateOnError OnError ;
93
124
#endregion
94
125
95
126
96
127
97
128
/// <summary>
98
- /// Initialize new instance of FileWatcherEx
129
+ /// Initialize new instance of <see cref="FileSystemWatcherEx"/>
99
130
/// </summary>
100
- /// <param name="folder "></param>
101
- public FileSystemWatcherEx ( string folder = "" )
131
+ /// <param name="folderPath "></param>
132
+ public FileSystemWatcherEx ( string folderPath = "" )
102
133
{
103
- FolderPath = folder ;
134
+ FolderPath = folderPath ;
104
135
}
105
136
106
137
@@ -120,7 +151,7 @@ public void Start()
120
151
121
152
InvokeChangedEvent ( SynchronizingObject , e ) ;
122
153
123
- void InvokeChangedEvent ( object sender , FileChangedEvent fileEvent )
154
+ void InvokeChangedEvent ( object ? sender , FileChangedEvent fileEvent )
124
155
{
125
156
if ( SynchronizingObject != null && SynchronizingObject . InvokeRequired )
126
157
{
@@ -139,7 +170,7 @@ void InvokeChangedEvent(object sender, FileChangedEvent fileEvent)
139
170
140
171
InvokeCreatedEvent ( SynchronizingObject , e ) ;
141
172
142
- void InvokeCreatedEvent ( object sender , FileChangedEvent fileEvent )
173
+ void InvokeCreatedEvent ( object ? sender , FileChangedEvent fileEvent )
143
174
{
144
175
if ( SynchronizingObject != null && SynchronizingObject . InvokeRequired )
145
176
{
@@ -158,7 +189,7 @@ void InvokeCreatedEvent(object sender, FileChangedEvent fileEvent)
158
189
159
190
InvokeDeletedEvent ( SynchronizingObject , e ) ;
160
191
161
- void InvokeDeletedEvent ( object sender , FileChangedEvent fileEvent )
192
+ void InvokeDeletedEvent ( object ? sender , FileChangedEvent fileEvent )
162
193
{
163
194
if ( SynchronizingObject != null && SynchronizingObject . InvokeRequired )
164
195
{
@@ -177,7 +208,7 @@ void InvokeDeletedEvent(object sender, FileChangedEvent fileEvent)
177
208
178
209
InvokeRenamedEvent ( SynchronizingObject , e ) ;
179
210
180
- void InvokeRenamedEvent ( object sender , FileChangedEvent fileEvent )
211
+ void InvokeRenamedEvent ( object ? sender , FileChangedEvent fileEvent )
181
212
{
182
213
if ( SynchronizingObject != null && SynchronizingObject . InvokeRequired )
183
214
{
@@ -244,25 +275,6 @@ void onError(ErrorEventArgs e)
244
275
_fsw . EnableRaisingEvents = true ;
245
276
}
246
277
247
- private void Thread_DoingWork ( CancellationToken cancelToken )
248
- {
249
- while ( true )
250
- {
251
- if ( cancelToken . IsCancellationRequested )
252
- return ;
253
-
254
- try
255
- {
256
- var e = _fileEventQueue . Take ( cancelToken ) ;
257
- _processor . ProcessEvent ( e ) ;
258
- }
259
- catch ( OperationCanceledException )
260
- {
261
- return ;
262
- }
263
- }
264
- }
265
-
266
278
267
279
/// <summary>
268
280
/// Stop watching files
@@ -284,7 +296,6 @@ public void Stop()
284
296
}
285
297
286
298
287
-
288
299
/// <summary>
289
300
/// Dispose the FileWatcherEx instance
290
301
/// </summary>
@@ -293,7 +304,30 @@ public void Dispose()
293
304
if ( _fsw != null )
294
305
{
295
306
_fsw . Dispose ( ) ;
307
+ GC . SuppressFinalize ( this ) ;
296
308
}
297
309
}
298
310
311
+
312
+
313
+ private void Thread_DoingWork ( CancellationToken cancelToken )
314
+ {
315
+ while ( true )
316
+ {
317
+ if ( cancelToken . IsCancellationRequested )
318
+ return ;
319
+
320
+ try
321
+ {
322
+ var e = _fileEventQueue . Take ( cancelToken ) ;
323
+ _processor ? . ProcessEvent ( e ) ;
324
+ }
325
+ catch ( OperationCanceledException )
326
+ {
327
+ return ;
328
+ }
329
+ }
330
+ }
331
+
332
+
299
333
}
0 commit comments