2010-07-14 2 views
13

네트워크 디렉터리를 모니터링하고 Windows Server 2008 컴퓨터에서 실행중인 도구를 작성하고있는 경우 FileSystemWatcher의 OnChanged 이벤트가 네트워크 드라이브에있는 파일에서 올바르게 시작됩니다. Windows 7을 사용하지 않고 복사 한 파일의 양이 Windows 7 컴퓨터에서 (19) 한 번에 19 개가 넘는 경우 어떤 이유로 파일이 개별적으로 수행되는 경우 작동하지만 이벤트가 발생하지 않습니다. 이 문제를 해결할 수있는 방법이 있습니까? 아니면 Windows 7 커널이 FSW 이벤트와 함께 작동하는 것입니까?FileSystemWatcher 및 windows 7

명확히하기 위해 XP 시스템에서 복사 할 때 수천 개의 파일에서 작동합니다. (소프트웨어는 여전히 2008 서버 시스템에 있습니다.)

MSDN에서

답변

22

:

윈도우 운영 체제는은 FileSystemWatcher에 의해 생성 된 버퍼에 파일 변경의 구성 요소를 알려줍니다. 짧은 시간 내에 많은 변경 사항이 있으면 버퍼가 오버플로 될 수 있습니다. 이로 인해 구성 요소가 디렉토리의 변경 사항을 추적하지 못하며 담요 알림 만 제공합니다. InternalBufferSize 속성을 사용하여 버퍼 크기를 늘리면 비 페이징 메모리가 디스크로 스왑 될 수 없기 때문에 비용이 많이 들기 때문에 버퍼를 작게 유지하면서 파일 변경 이벤트를 놓치지 않도록하십시오. 버퍼 오버플로를 방지하려면 원치 않는 변경 알림을 필터링 할 수 있도록 NotifyFilterIncludeSubdirectories 속성을 사용하십시오.

버퍼 크기를 늘리는 것만으로는 충분하지 않고 한 번에 이벤트를 트리거하는 파일 수를 제어 할 수없는 경우 추가 폴링을 추가해야합니다.

또한이 관련 질문을 참조 :

FileSystemWatcher does not work properly when many files are added to the directory at the same time…

업데이트 :

단순히 버퍼 크기를 증가하지만이 신중하게해야하는 것이 유혹 수 있습니다. 실제로, 네트워크 액세스에 관해서는 64k 제한이 있습니다. 버퍼 길이가 64KB보다 큰이며, 응용 프로그램이 네트워크를 통해 디렉토리를 모니터링 할 때

ReadDirectoryChangesW이 ERROR_INVALID_PARAMETER 함께 실패 다음 FileSystemWatcher 클래스는이 제한이 ReadDirectoryChangesW 속해있는 Windows API 함수를 사용하고 있습니다. 이는 기본 파일 공유 프로토콜의 패킷 크기 제한 때문입니다.

는 버퍼 크기를 수정하는 비용에 대한 깊은 이해를 얻고 싶은 경우에 당신이 여기에 마이크로 소프트의 월터 왕의 포스트를 살펴이 있어야합니다 인용

FileSystemWatcher across the network (전체 게시물 아래)

내가 FileSystemWatcher.InternalBufferSize 의 문서는 네트워크모니터링 버퍼 크기에 대해 매우 분명한 언급하지 않았다 미안 해요경로. 네트워크 경로를 모니터링 할 때 64K 을 초과하지 않는 것이 좋습니다.

FileSystemWatcher는 기본적으로 a입니다.Win32 ReadDirectoryChangesW API 용 래퍼. ReadDirectoryChangesW를 사용하려면 OS가 변경 사항으로 채울 버퍼를 지정하십시오. 그러나, ReadDirectoryChangesW 문서 에 언급되지 않은 (그러나 FileSystemWatcher 구성 문서에서 암시되는) 어떤 는 파일 시스템이 업데이트 할 수있는 기회가 될 때까지 일시적으로 변경 정보 를 저장하기 위해 내부 커널에게 버퍼를 생성하는 것입니다 사용자 버퍼 커널 버퍼는 ReadDirectoryChangesW에 지정된 크기와 동일한 크기 인 이며 비 페이징 풀링 된 메모리에 으로 생성됩니다. FileSystemWatcher/ ReadDirectoryChangesW가 호출 될 때마다/ 이 호출 될 때마다 새 커널 버퍼가 으로 생성됩니다.

커널 메모리 (페이징 및 비 페이징) 풀 장치 드라이버 및 사용 다른 커널 컴포넌트 시스템 주소 공간에서 방치된다. 그들은 으로 동적으로 커지고 수축됩니다. 이 필요합니다. 풀의 현재 크기는 작업 관리자의 성능 탭으로 이동하면 쉽게 확인할 수 있습니다. 풀은 부팅시에 계산되는 최대 값에 도달 할 때까지 동적으로 으로 증가하며 사용 가능한 시스템 리소스 (주로 RAM)에 따라 달라집니다. 이 최대 값에 도달하려고하지 않거나 다양한 시스템 서비스 및 드라이버 이 실패하기 시작합니다. 그러나이 계산 된 최대 값은 쉽게 사용할 수 없습니다. . 최대 풀 크기를 확인하려면 커널 디버거를 사용해야합니다. 메모리 풀에 대한 자세한 내용을 보려면 MSPress 서적의 7 장을 참조하십시오. Solomon 및 Russinovich.

염두에두고 어떤 크기의 버퍼 에 권장 사항이 없습니다. 시스템 풀의 현재 및 최대 크기는 으로 클라이언트에서 클라이언트로 다양합니다. 그러나 각 FileSystemWatcher/ ReadDirectoryChangesW 버퍼에 대해을 64k 이상 사용해서는 안됩니다. 이 은 네트워크 액세스가있는 64k 제한이 으로 ReadDirectoryChangesW에 기록되어 있다는 사실에서 기인합니다. 그러나 결국 을 사용하여 에서 버퍼를 조정할 수 있도록 다양한 대상 시스템에서 의 예상 대상 시스템을 테스트해야합니다.

오버 헤드가 닷넷 응용 프로그램과 연관 나는 는 Win32 ReadDirectoryChangesW 프로그램 이 같은 버퍼 사이즈로 더 나은 성능을 달성 할 수있을 것으로 생각된다. 그러나, 매우 빠르고 많은 파일 변경, 버퍼 오버런이 불가피 되며 의 변화를 감지 할 디렉토리를 열거하는 등 수동으로 같은 오버런이 발생하면 개발자는 경우를 처리해야 할 을 것입니다. 결론적으로

은은 FileSystemWatcher 및 ReadDirectoryChangesW는 제한이 예정되어있는 경량 파일 변경 감지 메커니즘입니다. 변경 저널 우리가 중간 무게의 솔루션을 고려해야 할 또 다른 메커니즘이지만, 은 여전히 ​​제한이있을 것입니다 : 전용 파일 시스템 필터를 드라이버를 쓰기에

http://msdn.microsoft.com/en-us/library/aa363798%28VS.85%29.aspx

중량이 무거운 솔루션이 될 것이라고 파일 시스템에 앉아 파일 시스템 이 변경되고 모니터합니다. 물론 이것은 가장 복잡한 접근 방법이 될 것입니다. 대부분의 바이러스 스캐너, 백업 소프트웨어 및 파일 과 같은 시스템 모니터링 유틸리티 filemon (www.sysinternals.com) 필터 드라이버를 구현합니다.

위의 설명을 참조하면 문제의 근본 원인을 파악할 수 있습니다. . 자세한 정보가 필요하면 에게 회신하여주십시오. 고맙습니다.

+0

그냥 작은 추가 : 기본 버퍼 크기는 8192 –

4

FileSystemWatcher를 사용하여 여러 번 시도한 결과 나는 포기했습니다. 잘못된 시간에 잘못 입력하면 이벤트가 올바르게 실행되지 않습니다. 솔직히 .net 프레임 워크에서 최악의 클래스 중 하나라고 생각합니다. 필자는 항상 System.Timer를 사용하는 클래스를 작성하고 x 밀리 초가 지나면 디렉토리, 파일을 수동으로 검사합니다. 예, 더 많은 작업이 필요합니다. 예, 약간의 PITA가 될 수 있지만 작성한 후에는 원하는 곳 어디에서나 사용할 수 있습니다. FileSystemWatcher가 광고 된대로 작동했으면 좋겠지 만 그렇게하지 못했습니다.

+0

내가'FileSystemWatcher' 분명 모든 상황에서 적합하지 않은 것에 동의합니다. 그러나 간단한 디렉토리 열거로 수행하기 어려운 기능 중 하나는 파일 이름 변경을 감지하는 것입니다. 파일 속성 비교, 추론, MD5 합계 등을 사용하여 수행 할 수 있지만 번거 롭습니다. – stakx

+0

@stakx, 그건 사실입니다. 나는 결코 파일 이름 변경을 확인하려고 시도한 적이 없습니다. 나는 결코 그것을 사용하지 않는 그 반에 의해 그렇게 불에 타 버렸다. – Justin

2

FileSystemWatcher 이벤트가 발생하는 대부분의 경우이 목록이 불완전 할 수 있으므로 개체에서 전달되는 파일을 무시합니다.

단순히 FileSystemWatcher 개체가 모니터링하는 디렉터리를 크롤링하고 FileSystemWatcher 버퍼에없는 파일을 찾기 위해 수동 검색을 수행합니다. 정말 우아한 것은 아니지만 파일을 놓치지 않을 것입니다.

+0

그것은 OP가 이야기하고있는 불일치와 완전히 별개의 문제처럼 보입니다. – Chad

+0

@Chad : 이것은 어떻게 완전히 관련이없는 것 같습니까? OP의 문제를 해결하는 방법과 똑같은 것 같아요. –

+0

은 OP에서 이벤트가 전혀 실행되지 않는다고 말하기 때문에 발생합니다. Laurens는 * 이벤트가 발생할 때 * 수동으로 디렉토리를 확인하지만 이벤트가 처음에는 실행되지 않으면 OP가이를 수행 할 수 없다고 제안합니다. 따라서 Laurens의 코멘트는 OP가보고있는 것과 동일한 문제에 관한 것이 아닙니다. 적어도 Laurens의 의견과 관련하여 OP 질문을 읽은 것입니다. – Chad

0

파일이 특정 임계 값 이상일 때 이것은 정말 신뢰할 수없는 클래스입니다. 이벤트가 초기 복사본에서 약 7 회 발사 된 다음 파일 전송 대화 상자가 완료되면 다른 7 개의 이벤트가 발생합니다.이 문제는 FSW를 지원하는 모든 OS'es. Windows 7 (아직 Vista를 사용해 보지 않았 음)은 한 번에 하나 또는 한 번에 하나씩 파일 만 허용하지만 XP 컴퓨터에서 네트워크 드라이브로 파일을 가져다 놓으면 아무 문제없이 즉시 수천 개의 파일을 읽을 수 있습니다. 이것은 XP에서 7 로의 ReadDirectoryChangesW의 변경 일 수 있습니다. 지난 19 개 파일 이제는 어떤 이벤트도 실행할 수 없으므로 지금은 내 도구의 "기능"이 될 것입니다. 누군가 다른 정보가 있다면 기꺼이 공헌하십시오. 때문에 귀하의 FileSystemWatcher.Path 속성의

-1

당신이에서라도 + 패러랠 데스크톱 + Windows를 사용하는 경우, 귀하의 코드가 작동하지 않습니다 은 맥 경로에 대상, 그것은 UNC 경로, 그것은 지원되지 않습니다!

enter image description here