Skip to content

Commit 2558b65

Browse files
authored
Merge pull request #14 from samba2/feature/refactor_file_watcher
Feature/refactor file watcher
2 parents d265e16 + 27cc437 commit 2558b65

12 files changed

+603
-491
lines changed

Source/Demo/Form1.Designer.cs

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/Demo/Form1.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public Form1()
1616

1717
private void BtnStart_Click(object sender, EventArgs e)
1818
{
19-
_fw = new FileSystemWatcherEx(txtPath.Text.Trim());
19+
_fw = new FileSystemWatcherEx(txtPath.Text.Trim(), FW_OnLog);
2020

2121
_fw.OnRenamed += FW_OnRenamed;
2222
_fw.OnCreated += FW_OnCreated;
@@ -26,7 +26,7 @@ private void BtnStart_Click(object sender, EventArgs e)
2626

2727
_fw.SynchronizingObject = this;
2828
_fw.IncludeSubdirectories = true;
29-
29+
3030
_fw.Start();
3131

3232
btnStart.Enabled = false;
@@ -76,7 +76,10 @@ private void FW_OnRenamed(object? sender, FileChangedEvent e)
7676
e.FullPath) + "\r\n";
7777
}
7878

79-
79+
private void FW_OnLog(string value)
80+
{
81+
txtConsole.Text += $@"[log] {value}" + "\r\n";
82+
}
8083

8184
private void BtnStop_Click(object sender, EventArgs e)
8285
{
@@ -105,7 +108,6 @@ private void BtnSelectFolder_Click(object sender, EventArgs e)
105108

106109
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
107110
{
108-
_fw.Stop();
109111
_fw.Dispose();
110112
}
111113
}

Source/Demo/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Manual Testing
2+
--------------
3+
4+
This little application is helpful for interactive testing of the library.
5+
6+
Symlinks
7+
--------
8+
To create a symlink directory on Windows, use `mklink`.
9+
Example: `mklink /D my-symbolic-link c:\temp\target-directory`

Source/FileWatcherEx/FileSystemWatcherEx.cs

+22-36
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public class FileSystemWatcherEx : IDisposable, IFileSystemWatcherEx
1717
private EventProcessor? _processor;
1818
private readonly BlockingCollection<FileChangedEvent> _fileEventQueue = new();
1919

20-
private FileWatcher? _watcher;
21-
private IFileSystemWatcherWrapper? _fsw;
20+
private SymlinkAwareFileWatcher? _watcher;
2221
private Func<IFileSystemWatcherWrapper>? _fswFactory;
22+
private readonly Action<string> _logger;
2323

2424
// Define the cancellation token.
2525
private CancellationTokenSource? _cancelSource;
@@ -86,6 +86,7 @@ public string Filter
8686

8787
#endregion
8888

89+
8990
#region Public Events
9091

9192
/// <summary>
@@ -134,11 +135,13 @@ public string Filter
134135
/// Initialize new instance of <see cref="FileSystemWatcherEx"/>
135136
/// </summary>
136137
/// <param name="folderPath"></param>
137-
public FileSystemWatcherEx(string folderPath = "")
138+
/// <param name="logger">Optional Action to log out library internals</param>
139+
public FileSystemWatcherEx(string folderPath = "", Action<string>? logger = null)
138140
{
139141
FolderPath = folderPath;
142+
_logger = logger ?? (_ => {}) ;
140143
}
141-
144+
142145

143146
/// <summary>
144147
/// Start watching files
@@ -233,10 +236,10 @@ void InvokeRenamedEvent(object? sender, FileChangedEvent fileEvent)
233236
}
234237
}, (log) =>
235238
{
236-
Console.WriteLine(string.Format("{0} | {1}", Enum.GetName(typeof(ChangeType), ChangeType.LOG), log));
239+
Console.WriteLine($"{Enum.GetName(typeof(ChangeType), ChangeType.LOG)} | {log}");
237240
});
238241

239-
_cancelSource = new();
242+
_cancelSource = new CancellationTokenSource();
240243
_thread = new Thread(() => Thread_DoingWork(_cancelSource.Token))
241244
{
242245
// this ensures the thread does not block the process from terminating!
@@ -247,40 +250,32 @@ void InvokeRenamedEvent(object? sender, FileChangedEvent fileEvent)
247250

248251

249252
// Log each event in our special format to output queue
250-
void onEvent(FileChangedEvent e)
253+
void OnEvent(FileChangedEvent e)
251254
{
252255
_fileEventQueue.Add(e);
253256
}
254257

255258

256-
// OnError
257-
void onError(ErrorEventArgs e)
259+
void OnError(ErrorEventArgs e)
258260
{
259261
if (e != null)
260262
{
261-
OnError?.Invoke(this, e);
263+
this.OnError?.Invoke(this, e);
262264
}
263265
}
264266

265-
266-
// Start watcher
267-
_watcher = new FileWatcher();
268-
269-
_fsw = _watcher.Create(FolderPath, onEvent, onError, FileSystemWatcherFactory);
270-
271-
foreach (var filter in Filters)
267+
_watcher = new SymlinkAwareFileWatcher(FolderPath, OnEvent, OnError, FileSystemWatcherFactory, _logger)
272268
{
273-
_fsw.Filters.Add(filter);
274-
}
275-
276-
_fsw.NotifyFilter = NotifyFilter;
277-
_fsw.IncludeSubdirectories = IncludeSubdirectories;
278-
_fsw.SynchronizingObject = SynchronizingObject;
279-
280-
// Start watching
281-
_fsw.EnableRaisingEvents = true;
269+
NotifyFilter = NotifyFilter,
270+
IncludeSubdirectories = IncludeSubdirectories,
271+
SynchronizingObject = SynchronizingObject,
272+
EnableRaisingEvents = true
273+
};
274+
Filters.ToList().ForEach(filter => _watcher.Filters.Add(filter));
275+
_watcher.Init();
282276
}
283277

278+
284279
internal void StartForTesting(
285280
Func<string, FileAttributes> getFileAttributesFunc,
286281
Func<string, DirectoryInfo[]> getDirectoryInfosFunc)
@@ -297,12 +292,6 @@ internal void StartForTesting(
297292
/// </summary>
298293
public void Stop()
299294
{
300-
if (_fsw != null)
301-
{
302-
_fsw.EnableRaisingEvents = false;
303-
_fsw.Dispose();
304-
}
305-
306295
_watcher?.Dispose();
307296

308297
// stop the thread
@@ -316,14 +305,12 @@ public void Stop()
316305
/// </summary>
317306
public void Dispose()
318307
{
319-
_fsw?.Dispose();
320308
_watcher?.Dispose();
321309
_cancelSource?.Dispose();
322310
GC.SuppressFinalize(this);
323311
}
324312

325313

326-
327314
private void Thread_DoingWork(CancellationToken cancelToken)
328315
{
329316
while (true)
@@ -342,6 +329,5 @@ private void Thread_DoingWork(CancellationToken cancelToken)
342329
}
343330
}
344331
}
345-
346-
347332
}
333+

0 commit comments

Comments
 (0)