FileSystemWatcher 대 폴링으로 파일 변경 사항 확인
로컬 또는 네트워크 드라이브의 디렉토리에서 생성되는 파일을 감시하는 응용 프로그램을 설정해야합니다.
FileSystemWatcher
타이머에 대한 폴링 또는 폴링이 가장 좋은 옵션 입니까? 과거에는 두 가지 방법을 모두 사용했지만 광범위하게 사용하지는 않았습니다.
두 가지 방법 중 어떤 문제 (성능, 안정성 등)가 있습니까?
프로덕션 및 테스트 환경에서 파일 시스템 감시자가 실패하는 것을 보았습니다. 이제는 편의상 고려하지만 신뢰할 수있는 것으로 간주하지 않습니다. 내 패턴은 파일 시스템 감시자와의 변경 사항을 감시하는 것이었지만 누락 된 파일 변경 사항을 포착하기 위해 때때로 폴링합니다.
편집 : UI가있는 경우 사용자에게 폴링 대신 변경 사항을 "새로 고칠 수있는"기능을 제공 할 수도 있습니다. 나는 이것을 파일 시스템 감시자와 결합시킬 것이다.
내가 가진 가장 큰 문제는 버퍼가 가득 차면 파일이 누락되는 것입니다. 파이로 쉽게 해결할 수 있습니다. 버퍼를 늘리기 만하면됩니다. 여기에는 파일 이름과 이벤트가 포함되므로 예상되는 파일 수 (시험 및 오류)로 늘리십시오. 페이징 아웃 할 수없는 메모리를 사용하므로 메모리가 부족하면 다른 프로세스가 페이징되도록 할 수 있습니다.
버퍼에 대한 MSDN 기사는 다음과 같습니다. FileSystemWatcher .. ::. InternalBufferSize 속성
MSDN 당 :
디스크로 교체 할 수없는 비 페이징 메모리에서 비롯되므로 버퍼 크기를 늘리면 비용이 많이들므로 버퍼를 가능한 작게 유지하십시오. 버퍼 오버 플로우를 피하려면 NotifyFilter 및 IncludeSubdirectories 특성을 사용하여 원하지 않는 변경 알림을 필터링하십시오.
한 번에 큰 일괄 처리가 예상되므로 16MB를 사용합니다. 잘 작동하고 파일을 놓치지 않습니다.
우리는 또한 하나를 처리하기 전에 모든 파일을 읽습니다. 파일 이름을 안전하게 캐시하여 (이 경우 데이터베이스 테이블에) 가져간 다음 처리하십시오.
파일 잠금 문제의 경우 1 초, 2 초, 4 초 등 파일 잠금이 풀릴 때까지 기다리는 프로세스를 생성합니다. 우리는 절대 폴링 하지 않습니다 . 이것은 약 2 년 동안 오류없이 생산되었습니다.
는 FileSystemWatcher
대기 변화의 수를 제공하는 버퍼 오버 플로우하는 경우 또한, 바쁜 시간 동안의 변화를 놓칠 수 있습니다. 이는 .NET 클래스 자체의 제한 사항이 아니라 기본 Win32 인프라의 제한 사항입니다. 경험상이 문제를 최소화하는 가장 좋은 방법은 가능한 빨리 알림을 대기열에서 빼고 다른 스레드에서 처리하는 것입니다.
위의 @ChillTemp에서 언급했듯이 감시자는 Windows가 아닌 공유에서 작동하지 않을 수 있습니다. 예를 들어, 마운트 된 Novell 드라이브에서는 전혀 작동하지 않습니다.
좋은 타협은 누락 된 변경 사항을 포착하기 위해 가끔씩 투표하는 것입니다.
또한 파일 시스템 감시자는 파일 공유에서 신뢰할 수 없습니다. 특히 파일 공유가 Windows 이외의 서버에서 호스팅되는 경우. FSW는 중요한 것에 사용해서는 안됩니다. 또는 가끔 빠진 것이 없는지 확인하기 위해 가끔 투표와 함께 사용해야합니다.
개인적 FileSystemWatcher
으로 프로덕션 시스템을 사용 했으며 정상적으로 작동했습니다. 지난 6 개월 동안 연중 무휴로 운영되는 단일 딸꾹질은 없었습니다. 단일 로컬 폴더 (공유)를 모니터링하고 있습니다. 처리해야하는 파일 조작 수가 비교적 적습니다 (하루에 10 개의 이벤트 발생). 내가 걱정했던 것은 아닙니다. 결정을 다시해야한다면 다시 사용하겠습니다.
나는 현재 FileSystemWatcher
평균 100 밀리 초마다 업데이트되는 XML 파일을 사용합니다 .
나는만큼이 같은 것을 발견했다 FileSystemWatcher
올바르게 구성하면 문제가해서는 안 로컬 파일을.
원격 파일 감시 및 비 Windows 공유에 대한 경험이 없습니다.
본질적으로 불신 FileSystemWatcher
하거나 여기에있는 다른 모든 사람들이 나열한 제한 (비 Windows 공유 및 원격 파일 감시)을 직접 경험 하지 않는 한 파일 폴링은 중복되어 오버 헤드가없는 것으로 간주합니다 .
나는 설문 조사와 함께 갈 것입니다.
네트워크 문제로 인해 FileSystemWatcher
오류 이벤트가 오버로드 될 때도 신뢰할 수 없습니다.
FileSystemWatcher
네트워크 공유를 사용 하는 데 문제가 있습니다 . 순수한 Windows 환경에 있으면 문제가되지 않지만 NFS 공유를보고 있었으며 NFS에 상태가 저장되지 않았기 때문에보고있는 파일이 변경 될 때 알림이 표시되지 않았습니다.
네트워크 드라이브에서 FSW에 큰 문제가있었습니다. 파일을 삭제하면 항상 오류 이벤트가 발생하고 삭제 된 이벤트는 발생하지 않습니다. 해결책을 찾지 못해 이제 FSW를 피하고 폴링을 사용합니다.
반면에 생성 이벤트는 제대로 작동했기 때문에 파일 생성 만 감시하면 FSW로 이동할 수 있습니다.
또한 공유 여부에 관계없이 로컬 폴더에 전혀 문제가 없었습니다.
FSW 와 폴링을 모두 사용 하는 것은 시간과 자원을 낭비하는 것이라고 생각합니다. 숙련 된 개발자가 제안한 것에 놀랐습니다. 폴링을 사용하여 "FSW 누락"을 확인해야하는 경우 FSW를 완전히 버리고 폴링 만 사용할 수 있습니다.
나는 현재 내가 FSW 사용 여부를 결정하려고 또는 내가 개발 프로젝트에 대한 폴링을. 답을 읽으면 FSW가 요구를 완벽하게 충족시키는 경우가 있고 다른 경우에는 폴링 이 필요한 경우가 있습니다 . 불행하게도, 아무 대답이 실제로 처리하지 않았다 성능 만이 "신뢰성"문제를, (어떤이있는 경우)의 차이. 질문의 해당 부분에 대답 할 수있는 사람이 있습니까?
편집 : nmclean FSW 폴링을 모두 사용한다는 상황이있을 수있는 이유 FSW 폴링을 모두 사용의 유효성의 점은 매우 합리적인 설명을 것으로 보인다 (당신이 관심이 있다면 당신은 코멘트에 토론을 읽을 수 있습니다) 된다 실력 있는. 나를 위해 (그리고 같은 의견을 가진 다른 사람) nmclean을 비추어 주셔서 감사합니다 .
다른 스레드를 사용하여 가능한 빨리 이벤트 메소드에서 돌아 오면 문제가 해결되었습니다.
private void Watcher_Created(object sender, FileSystemEventArgs e)
{
Task.Run(() => MySubmit(e.FullPath));
}
변경 대신 이벤트 작성 작업을위한 작업 솔루션
복사, 잘라 내기, 붙여 넣기, 이동에도 적용됩니다.
class Program
{
static void Main(string[] args)
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
FileSystemWatcher.Path = SourceFolderPath;
FileSystemWatcher.IncludeSubdirectories = false;
FileSystemWatcher.NotifyFilter = NotifyFilters.FileName; // ON FILE NAME FILTER
FileSystemWatcher.Filter = "*.txt";
FileSystemWatcher.Created +=FileSystemWatcher_Created; // TRIGGERED ONLY FOR FILE GOT CREATED BY COPY, CUT PASTE, MOVE
FileSystemWatcher.EnableRaisingEvents = true;
Console.Read();
}
static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
try
{
// DO SOMETING LIKE MOVE, COPY, ETC
File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
}
catch
{
}
}
}
정적 스토리지를 사용하는 파일 속성 변경 이벤트 동안이 파일 감시자에 대한 솔루션
class Program
{
static string IsSameFile = string.Empty; // USE STATIC FOR TRACKING
static void Main(string[] args)
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
FileSystemWatcher.Path = SourceFolderPath;
FileSystemWatcher.IncludeSubdirectories = false;
FileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
FileSystemWatcher.Filter = "*.txt";
FileSystemWatcher.Changed += FileSystemWatcher_Changed;
FileSystemWatcher.EnableRaisingEvents = true;
Console.Read();
}
static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
if (e.Name == IsSameFile) //SKIPS ON MULTIPLE TRIGGERS
{
return;
}
else
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
try
{
// DO SOMETING LIKE MOVE, COPY, ETC
File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
}
catch
{
}
}
IsSameFile = e.Name;
}
}
이것은 다중 트리거 이벤트의이 문제점에 대한 임시 해결책입니다.
I would say use polling, especially in a TDD scenario, as it is much easier to mock/stub the presence of files or otherwise when the polling event is triggered than to rely on the more "uncontrolled" fsw event. + to that having worked on a number of apps which were plagued by fsw errors.
참고URL : https://stackoverflow.com/questions/239988/filesystemwatcher-vs-polling-to-watch-for-file-changes
'development' 카테고리의 다른 글
GIT 병합 오류 "파일 병합 해제로 인해 커밋 할 수 없습니다" (0) | 2020.06.16 |
---|---|
Backbone.sync를 무시하는 방법? (0) | 2020.06.16 |
C ++에서의 __FILE__, __LINE__ 및 __FUNCTION__ 사용법 (0) | 2020.06.16 |
SQLAlchemy는 Django의 get_or_create에 해당합니까? (0) | 2020.06.16 |
Django가 사용자 정의 양식 매개 변수를 Formset에 전달 (0) | 2020.06.16 |