Skip to content

Commit 40cd11a

Browse files
committed
🐛 Adding semaphore to avoid issue on closing
1 parent 6451346 commit 40cd11a

File tree

1 file changed

+101
-67
lines changed

1 file changed

+101
-67
lines changed

Analogy/Managers/FilePoolingManager.cs

+101-67
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ internal class FilePoolingManager : ILogMessageCreatedHandler
1717
private readonly AnalogyLogMessageCustomEqualityComparer _customEqualityComparer;
1818
private readonly UCLogs _logUI;
1919
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);
2022

2123
private readonly object _sync;
2224
private DateTime _lastRead;
@@ -127,93 +129,125 @@ public void StopMonitoring()
127129

128130
private void WatchFile_Error(object sender, ErrorEventArgs e)
129131
{
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+
}
142152
}
143153

144154
private async void WatchFile_Renamed(object sender, RenamedEventArgs e)
145155
{
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
184158
{
185-
if (_readingInprogress || (Settings.EnableFilePoolingDelay && DateTime.Now.Subtract(_lastRead).TotalSeconds <= Settings.FilePoolingDelayInterval))
186-
return;
187-
_lastWriteTime = f.LastWriteTime;
188-
_lastRead = DateTime.Now;
189159
_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();
191172
}
192-
try
173+
finally
193174
{
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();
199176
}
200-
catch (Exception exception)
177+
}
178+
179+
private void WatchFile_Deleted(object sender, FileSystemEventArgs e)
180+
{
181+
_watcherSemaphore.Wait();
182+
try
201183
{
184+
_watchFile.EnableRaisingEvents = false;
202185
AnalogyLogMessage m = new()
203186
{
204-
Text = $"Error monitoring file {e.FullPath}. Reason {exception}",
187+
Text = $"{FileName} has been deleted. Stopping monitoring",
205188
FileName = FileName,
206189
Level = AnalogyLogLevel.Warning,
207190
Class = AnalogyLogClass.General,
208191
Date = DateTime.Now
209192
};
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+
}
212247
}
213248
finally
214249
{
215-
_readingInprogress = false;
216-
_watchFile.EnableRaisingEvents = true;
250+
_watcherSemaphore.Release();
217251
}
218252
}
219253
}

0 commit comments

Comments
 (0)