-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAssemblyWatcher.cs
110 lines (94 loc) · 3.61 KB
/
AssemblyWatcher.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.IO;
using System.Threading;
using System.Text;
namespace AutoUpdate {
//观察路径下的dll变更,在更新后的2秒左右刷新结果。
class AssemblyWatcher : IDisposable {
private string _path;
public string Path {
get { return _path; }
set {
if (_path != value) {
UnhookFiles();
_path = value;
HookFiles();
}
}
}
private FileSystemWatcher _watcher;
private Timer _timer;
public event EventHandler Changed;
private void HookFiles() {
if (string.IsNullOrEmpty(_path) ||
!Directory.Exists(_path)) {
return;
}
_watcher = new FileSystemWatcher(_path, "*.dll");
_watcher.Changed += _watcher_Changed;
_watcher.Created += _watcher_Changed;
_watcher.Deleted += _watcher_Changed;
_watcher.Renamed += _watcher_Changed;
_watcher.IncludeSubdirectories = true;
_watcher.EnableRaisingEvents = true;
_timer = new Timer(OnTime, null, new TimeSpan(0, 0, 2),new TimeSpan(0,0,2));
}
private int _lastWorkVersion;
private void OnTime(object state) {
var changedVersion = _changedVersion;
//更新最后一次处理的版本号
var lastVersion = Interlocked.Exchange(ref _lastWorkVersion, changedVersion);
if (lastVersion != changedVersion) {
var onchanged = this.Changed;
if (onchanged != null) {
onchanged(this, EventArgs.Empty);
}
}
}
private void UnhookFiles() {
if (string.IsNullOrEmpty(_path) ||
_watcher == null ||
!Directory.Exists(_path)) {
return;
}
_watcher.Changed -= _watcher_Changed;
_watcher.Created -= _watcher_Changed;
_watcher.Deleted -= _watcher_Changed;
_watcher.Renamed -= _watcher_Changed;
_watcher.Dispose();
_watcher = null;
if (_timer != null) {
_timer.Dispose();
_timer = null;
}
}
private int _changedVersion;
private void _watcher_Changed(object sender, FileSystemEventArgs e) {
//在文件发生变化后,标记文件已改动
//理论上,在单个文件发生改变时,可以仅更新单个文件的FileInfo,但是我不想把代码写的太复杂,所以就统一使用脏。
//在标记为脏后,定时器发起同步,很可能在同步的过程中又发生变更,所以我使用版本号的方式,这样就知道之后有没有再次发生改变。
Interlocked.Increment(ref _changedVersion);
}
#region IDisposable Support
private bool disposedValue = false; // 要检测冗余调用
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
if (disposing) {
if (_timer != null) {
_timer.Dispose();
_timer = null;
}
if (_watcher != null) {
_watcher.Dispose();
_watcher = null;
}
}
disposedValue = true;
}
}
public void Dispose() {
Dispose(true);
}
#endregion
}
}