@@ -17,6 +17,8 @@ internal class FilePoolingManager : ILogMessageCreatedHandler
17
17
private readonly AnalogyLogMessageCustomEqualityComparer _customEqualityComparer ;
18
18
private readonly UCLogs _logUI ;
19
19
private readonly List < IAnalogyLogMessage > _messages ;
20
+ //Instantiate a Singleton of the Semaphore with a value of 1. This means that only 1 thread can be granted access at a time.
21
+ static SemaphoreSlim _watcherSemaphore = new SemaphoreSlim ( 1 , 1 ) ;
20
22
21
23
private readonly object _sync ;
22
24
private DateTime _lastRead ;
@@ -127,93 +129,125 @@ public void StopMonitoring()
127
129
128
130
private void WatchFile_Error ( object sender , ErrorEventArgs e )
129
131
{
130
- _watchFile . EnableRaisingEvents = false ;
131
- _watchFile . Dispose ( ) ;
132
- AnalogyLogMessage m = new ( )
133
- {
134
- Text = $ "Error monitoring file { FileName } . Reason { e . GetException ( ) } ",
135
- FileName = FileName ,
136
- Level = AnalogyLogLevel . Critical ,
137
- Source = "Analogy" ,
138
- Class = AnalogyLogClass . General ,
139
- Date = DateTime . Now
140
- } ;
141
- OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , FileName ) ) ;
132
+ _watcherSemaphore . Wait ( ) ;
133
+ try
134
+ {
135
+ _watchFile . EnableRaisingEvents = false ;
136
+ _watchFile . Dispose ( ) ;
137
+ AnalogyLogMessage m = new ( )
138
+ {
139
+ Text = $ "Error monitoring file { FileName } . Reason { e . GetException ( ) } ",
140
+ FileName = FileName ,
141
+ Level = AnalogyLogLevel . Critical ,
142
+ Source = "Analogy" ,
143
+ Class = AnalogyLogClass . General ,
144
+ Date = DateTime . Now
145
+ } ;
146
+ OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , FileName ) ) ;
147
+ }
148
+ finally
149
+ {
150
+ _watcherSemaphore . Release ( ) ;
151
+ }
142
152
}
143
153
144
154
private async void WatchFile_Renamed ( object sender , RenamedEventArgs e )
145
155
{
146
- _watchFile . EnableRaisingEvents = false ;
147
- AnalogyLogMessage m = new ( )
148
- {
149
- Text = $ "{ FileName } has changed to { e . FullPath } from { e . OldName } . restarting monitoring",
150
- FileName = FileName ,
151
- Level = AnalogyLogLevel . Warning ,
152
- Source = "Analogy" ,
153
- Class = AnalogyLogClass . General ,
154
- Date = DateTime . Now
155
- } ;
156
- _watchFile . Dispose ( ) ;
157
- OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , FileName ) ) ;
158
- await Init ( ) ;
159
- }
160
-
161
- private void WatchFile_Deleted ( object sender , FileSystemEventArgs e )
162
- {
163
- _watchFile . EnableRaisingEvents = false ;
164
- AnalogyLogMessage m = new ( )
165
- {
166
- Text = $ "{ FileName } has been deleted. Stopping monitoring",
167
- FileName = FileName ,
168
- Level = AnalogyLogLevel . Warning ,
169
- Class = AnalogyLogClass . General ,
170
- Date = DateTime . Now
171
- } ;
172
- _watchFile . Dispose ( ) ;
173
- OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , FileName ) ) ;
174
- }
175
-
176
- private async void WatchFile_Changed ( object sender , FileSystemEventArgs e )
177
- {
178
- if ( _readingInprogress )
179
- return ;
180
- FileInfo f = new ( e . FullPath ) ;
181
- if ( _lastWriteTime == f . LastWriteTime )
182
- return ;
183
- lock ( _sync )
156
+ await _watcherSemaphore . WaitAsync ( ) ;
157
+ try
184
158
{
185
- if ( _readingInprogress || ( Settings . EnableFilePoolingDelay && DateTime . Now . Subtract ( _lastRead ) . TotalSeconds <= Settings . FilePoolingDelayInterval ) )
186
- return ;
187
- _lastWriteTime = f . LastWriteTime ;
188
- _lastRead = DateTime . Now ;
189
159
_watchFile . EnableRaisingEvents = false ;
190
- _readingInprogress = true ;
160
+ AnalogyLogMessage m = new ( )
161
+ {
162
+ Text = $ "{ FileName } has changed to { e . FullPath } from { e . OldName } . restarting monitoring",
163
+ FileName = FileName ,
164
+ Level = AnalogyLogLevel . Warning ,
165
+ Source = "Analogy" ,
166
+ Class = AnalogyLogClass . General ,
167
+ Date = DateTime . Now
168
+ } ;
169
+ _watchFile . Dispose ( ) ;
170
+ OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , FileName ) ) ;
171
+ await Init ( ) ;
191
172
}
192
- try
173
+ finally
193
174
{
194
- if ( e . ChangeType == WatcherChangeTypes . Changed )
195
- {
196
- _logUI . SetReloadColorDate ( FileProcessor . lastNewestMessage ) ;
197
- await FileProcessor . Process ( OfflineDataProvider , e . FullPath , _cancellationTokenSource . Token ) ;
198
- }
175
+ _watcherSemaphore . Release ( ) ;
199
176
}
200
- catch ( Exception exception )
177
+ }
178
+
179
+ private void WatchFile_Deleted ( object sender , FileSystemEventArgs e )
180
+ {
181
+ _watcherSemaphore . Wait ( ) ;
182
+ try
201
183
{
184
+ _watchFile . EnableRaisingEvents = false ;
202
185
AnalogyLogMessage m = new ( )
203
186
{
204
- Text = $ "Error monitoring file { e . FullPath } . Reason { exception } ",
187
+ Text = $ "{ FileName } has been deleted. Stopping monitoring ",
205
188
FileName = FileName ,
206
189
Level = AnalogyLogLevel . Warning ,
207
190
Class = AnalogyLogClass . General ,
208
191
Date = DateTime . Now
209
192
} ;
210
- OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , e . FullPath ) ) ;
211
- AnalogyLogManager . Instance . LogErrorMessage ( m ) ;
193
+ _watchFile . Dispose ( ) ;
194
+ OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , FileName ) ) ;
195
+ }
196
+ finally
197
+ {
198
+ _watcherSemaphore . Release ( ) ;
199
+ }
200
+ }
201
+
202
+ private async void WatchFile_Changed ( object sender , FileSystemEventArgs e )
203
+ {
204
+ await _watcherSemaphore . WaitAsync ( ) ;
205
+ try
206
+ {
207
+ if ( _readingInprogress )
208
+ return ;
209
+ FileInfo f = new ( e . FullPath ) ;
210
+ if ( _lastWriteTime == f . LastWriteTime )
211
+ return ;
212
+ lock ( _sync )
213
+ {
214
+ if ( _readingInprogress || ( Settings . EnableFilePoolingDelay && DateTime . Now . Subtract ( _lastRead ) . TotalSeconds <= Settings . FilePoolingDelayInterval ) )
215
+ return ;
216
+ _lastWriteTime = f . LastWriteTime ;
217
+ _lastRead = DateTime . Now ;
218
+ _watchFile . EnableRaisingEvents = false ;
219
+ _readingInprogress = true ;
220
+ }
221
+ try
222
+ {
223
+ if ( e . ChangeType == WatcherChangeTypes . Changed )
224
+ {
225
+ _logUI . SetReloadColorDate ( FileProcessor . lastNewestMessage ) ;
226
+ await FileProcessor . Process ( OfflineDataProvider , e . FullPath , _cancellationTokenSource . Token ) ;
227
+ }
228
+ }
229
+ catch ( Exception exception )
230
+ {
231
+ AnalogyLogMessage m = new ( )
232
+ {
233
+ Text = $ "Error monitoring file { e . FullPath } . Reason { exception } ",
234
+ FileName = FileName ,
235
+ Level = AnalogyLogLevel . Warning ,
236
+ Class = AnalogyLogClass . General ,
237
+ Date = DateTime . Now
238
+ } ;
239
+ OnNewMessages ? . Invoke ( this , ( new List < IAnalogyLogMessage > { m } , e . FullPath ) ) ;
240
+ AnalogyLogManager . Instance . LogErrorMessage ( m ) ;
241
+ }
242
+ finally
243
+ {
244
+ _readingInprogress = false ;
245
+ _watchFile . EnableRaisingEvents = true ;
246
+ }
212
247
}
213
248
finally
214
249
{
215
- _readingInprogress = false ;
216
- _watchFile . EnableRaisingEvents = true ;
250
+ _watcherSemaphore . Release ( ) ;
217
251
}
218
252
}
219
253
}
0 commit comments