최근에 CSVFS 클러스터 파일 서버를 방문했습니다. 나는 노드 변경, 그것은변경하는 노드를 처리하는 가장 좋은 방법은 무엇입니까? - C# File Watcher 및 Clustered File Server
너무 많은 변화를 한 번 디렉토리에
다음은 전문가에 오류가있는 버퍼 오버 플로우가 발생 할 때마다 파일 OnCreated
및 OnRenamed
이벤트를 4 디렉토리를 모니터링하는 것 감시자하지만이 가 자동으로 다시 시작되고 프로세스는 계속 작동하지만 OnCreated
/OnRenamed
이벤트가 발생하면 오류 쓰기가 시작됩니다.
폐기 된 개체에 액세스 할 수 없습니다.
개체 이름 : 'FileSystemWatcher'. 나는이 작업을 수행 할 수 있다면 System.IO.FileSystemWatcher.StartRaisingEvents에서
() System.IO.FileSystemWatcher.set_EnableRaisingEvents에서
(부울 값) 아래OnCreated
방법에서
, 그것은 작동 하는가?
watchit = source as FileSystemWatcher;
는 사실은 다른 곳에서는 새로 만든 FileSystemWatcher
에 watchit
할당하지 않습니다.
더 많은 정보/코드
프로세스가 처음 시작될 때 관찰자가 foreach 루프를 통해 생성된다. FileChange
은 단순히 변경 유형을 결정하고 약간의 작업을 수행 한 다음 변경 유형에 대한 올바른 작업을 트리거하는 메소드입니다.
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
전역 설정된 정적 FileSystemWatcher
이다.
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;
}
이들은 나의 오류 처리 방법입니다.
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) { }
}