Wir sind vor kurzem zu einem CSVFS Clustered File Server gegangen. Ich habe einen Beobachter-Datei, die 4-Verzeichnisse für OnCreated
und OnRenamed
Eventss Überwachung aber immer dann, wenn der Knoten ändert, ist es einen Pufferüberlauf mit dem FehlerDer beste Weg, um wechselnde Knoten zu behandeln? - C# File Watcher und Clustered File Server
Zu viele Änderungen auf einmal
im Verzeichnis bewirkt, dass die die Beobachter werden automatisch neu gestartet und der Prozess läuft weiter, aber beginnt Fehler zu schreiben, wenn die OnCreated
/OnRenamed
Ereignisse ausgelöst werden.
Zugriff auf ein entsorgtes Objekt nicht möglich.
Objektname: 'FileSystemWatcher'.
bei System.IO.FileSystemWatcher.StartRaisingEvents()
bei System.IO.FileSystemWatcher.set_EnableRaisingEvents (Boolean Wert)
Im OnCreated
Methode unten, wenn ich dies zu tun war, sollte es funktionieren?
watchit = source as FileSystemWatcher;
ich eigentlich gar nicht vergeben die neu geschaffene FileSystemWatcher
-watchit
anderswo.
Weitere Details/code
Die Beobachter werden über eine foreach-Schleife erstellt, wenn der Prozess zunächst beginnt. FileChange
ist einfach eine Methode, die die Art der Änderung bestimmt, ein wenig Arbeit leistet und dann die richtige Aktion für den Änderungstyp auslöst.
foreach (string subDir in subDirs)
{
string localFolder = $"{subDir}";
watchit = new FileSystemWatcher
{
Path = localFolder,
EnableRaisingEvents = true,
IncludeSubdirectories = false,
NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime,
Filter = watchFor,
InternalBufferSize = 65536,
SynchronizingObject = null //,
};
watchit.Changed += FileChange;
watchit.Created += FileChange;
watchit.Deleted += FileChange;
watchit.Renamed += OnRename;
watchit.Error += OnError;
watchit.EnableRaisingEvents = true;
watchers.Add(watchit);
Console.WriteLine($"watching {subDir} for {watchFor}");
}
watchit
ist eine statische FileSystemWatcher
global festgelegt.
private static async Task<int> OnCreated<T>(object source, FileSystemEventArgs e, string ext)
{
int insertResult = 0;
try
{
watchit.EnableRaisingEvents = false;
EventLogWriter.WriteEntry("File: " + e.FullPath + " " + e.ChangeType);
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType + " " + DateTime.Now);
insertResult = await FileHandler.FileHandlers().ConfigureAwait(false);
watchit.EnableRaisingEvents = true;
// if (insertResult > 0) File.Delete(e.FullPath);
}
catch (Exception ex)
{
Logger.Trace($"{ex.Message} {ex.StackTrace} {ex.InnerException}");
EventLogWriter.WriteEntry($"{ex.Message} {ex.StackTrace} {ex.InnerException}",
EventLogEntryType.Error);
watchit.EnableRaisingEvents = true;
}
finally
{
watchit.EnableRaisingEvents = true;
}
return insertResult;
}
Dies sind meine Fehlerbehandlungsmethoden.
private static void OnError(object source, ErrorEventArgs e)
{
if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
{
EventLogWriter.WriteEntry($"Error: File System Watcher internal buffer overflow at {DateTime.Now}", EventLogEntryType.Warning);
}
else
{
EventLogWriter.WriteEntry($"Error: Watched directory not accessible at {DateTime.Now}", EventLogEntryType.Warning);
}
MailSend.SendUploadEmail($"ASSIST NOTES: {e.GetException().Message}", "The notes service had a failure and should be restarted.", "admins", e.GetException(), MailPriority.High);
NotAccessibleError(source as FileSystemWatcher, e);
}
/// <summary>
/// triggered on accessible error.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="e">The <see cref="ErrorEventArgs"/> instance containing the event data.</param>
private static void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e)
{
EventLogWriter.WriteEntry($"Not Accessible issue. {e.GetException().Message}" + DateTime.Now.ToString("HH:mm:ss"));
int iMaxAttempts = 120;
int iTimeOut = 30000;
int i = 0;
string watchPath = source.Path;
string watchFilter = source.Filter;
int dirExists = 0;
try
{
dirExists = Directory.GetFiles(watchPath).Length;
}
catch (Exception) { }
try
{
while (dirExists == 0 && i < iMaxAttempts)
{
i += 1;
try
{
source.EnableRaisingEvents = false;
if (!Directory.Exists(source.Path))
{
EventLogWriter.WriteEntry(
"Directory Inaccessible " + source.Path + " at " +
DateTime.Now.ToString("HH:mm:ss"));
Console.WriteLine(
"Directory Inaccessible " + source.Path + " at " +
DateTime.Now.ToString("HH:mm:ss"));
System.Threading.Thread.Sleep(iTimeOut);
}
else
{
// ReInitialize the Component
source.Dispose();
source = null;
source = new System.IO.FileSystemWatcher();
((System.ComponentModel.ISupportInitialize)(source)).BeginInit();
source.EnableRaisingEvents = true;
source.Filter = watchFilter;
source.Path = watchPath;
source.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime;
source.Created += FileChange;
source.Renamed += OnRename;
source.Error += new ErrorEventHandler(OnError);
((System.ComponentModel.ISupportInitialize)(source)).EndInit();
EventLogWriter.WriteEntry(
$"Restarting watcher {watchPath} at " + DateTime.Now.ToString("HH:mm:ss"));
dirExists = 1;
}
}
catch (Exception error)
{
EventLogWriter.WriteEntry($"Error trying Restart Service {watchPath} " + error.StackTrace +
" at " + DateTime.Now.ToString("HH:mm:ss"));
source.EnableRaisingEvents = false;
System.Threading.Thread.Sleep(iTimeOut);
}
}
//Starts a new version of this console appp if retries exceeded
//Exits current process
var runTime = DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime();
if (i >= 120 && runTime > TimeSpan.Parse("0:00:30"))
{
Process.Start(Assembly.GetExecutingAssembly().Location);
Environment.Exit(666);
}
}
catch (Exception erw) { }
}