System.IO.FileSystemWatcher para monitorar uma pasta de rede-servidor - Considerações sobre o desempenho

StackOverflow https://stackoverflow.com/questions/151804

Pergunta

Eu quero ver uma árvore de pastas em um servidor de rede para mudanças. Os arquivos têm uma extensão específica. Existem cerca de 200 pastas na árvore e cerca de 1200 ficheiros com a extensão estou assistindo.

Eu não posso escrever um serviço a ser executado no servidor (fora dos limites!) Para que a solução tem de ser local para o cliente. Pontualidade não é particularmente importante. Eu posso viver com um minuto ou mais de atraso nas notificações. Estou assistindo para Criar, excluir, renomear e alterações.

Será que usando o .NET System.IO.fileSystemWatcher criar muito de uma carga sobre o servidor?

Como cerca de 10 observadores independentes de reduzir o número de pastas / arquivos sendo vigiado? (Até 200 de 700 pastas, 1200 de 5500 arquivos no total) mais tráfego de rede em vez de menos? Meus pensamentos são uma remodelação no servidor para colocar os arquivos vistos sob uma árvore. Eu não pode sempre ter esta opção, portanto, a equipe de observadores.

Suponho que a outra solução é uma verificação periódica se o FSW cria uma carga excessiva no servidor, ou se ele não funciona para um monte de razões tipo SysAdmin.

Existe uma maneira melhor de fazer isso?

Foi útil?

Solução

A partir de um ponto de carga de vista do servidor, usando o IO .FileSystemWatcher para notificações de alteração remotos no cenário que você descreve é ??provavelmente o método mais eficiente possível. Ele usa o FindFirstChangeNotification e ReadDirectoryChangesW funções da API Win32 internamente, que por sua vez se comunicar com o redirecionador de rede de forma otimizada (assumindo que a rede padrão do Windows : se um redirecionador de terceiros é usado, e ele não suporta a funcionalidade necessária, as coisas não irá funcionar em todos). O wrapper .NET também usa assíncrono I / O e tudo, garantindo mais eficiência máxima.

O único problema com esta solução é que não é muito confiável. Para além de ter de lidar com conexões de rede indo embora temporariamente (o que não é muito de um problema, já que IO.FileSystemWatcher irá disparar um evento de erro neste caso, você pode lidar com), o mecanismo subjacente tem certas limitações fundamentais. A partir da documentação MSDN para as funções da API Win32:

  • ReadDirectoryChangesW falhar com ERROR_INVALID_PARAMETER quando o comprimento do tampão é maior do que 64 kb e a aplicação é a monitorização de um directório através da rede. Isto é devido a uma limitação do tamanho do pacote com os protocolos de compartilhamento de arquivos subjacentes

  • nofollow notificações não podem ser devolvidos ao chamar FindFirstChangeNotification para um sistema de arquivos remoto

Em outras palavras: sob carga alta (quando você precisaria de um grande buffer) ou, pior, em circunstâncias não especificadas aleatórios, você pode não obter as notificações que você espera. Isto é ainda um problema com os observadores do sistema de arquivos locais, mas é muito mais um problema na rede. Outra questão aqui em detalhes para os problemas de confiabilidade inerentes com a API em um pouco mais detalhadamente.

Ao usar observadores do sistema de arquivos, a sua aplicação deve ser capaz de lidar com essas limitações. Por exemplo:

  • Se os arquivos que você está procurando têm números de seqüência, armazenar o último número de seqüência que você foi notificado sobre, então você pode procurar por 'lacunas' sobre as notificações futuras e processar os arquivos para o qual você não conseguir notificado;

  • Ao receber uma notificação, sempre fazer uma varredura do diretório completo. Isto pode soar muito mal, mas desde que a verificação for event-driven, ainda é muito mais eficiente do que a sondagem mudo. Além disso, enquanto você manter o número total de arquivos em um único diretório, bem como o número de diretórios para digitalizar, sob um mil ou mais, o impacto desta operação no desempenho deve ser bastante mínima de qualquer maneira.

Criação de vários ouvintes é algo que você deve evitar, tanto quanto possível: se alguma coisa, isso vai tornar as coisas ainda menos de confiança ...

De qualquer forma, se você absolutamente Have para os observadores do sistema de arquivos uso, as coisas podem funcionar bem, desde que você está ciente das limitações, e não esperar 1: Notificação 1 para cada arquivo modificado /criada.

Então, se você tem outras opções (essencialmente, com o processo de escrever os arquivos notificá-lo de uma forma baseada sistema não-file: qualquer método RPC regular será uma melhoria ...), essas são definitivamente vale a pena a partir de um ponto de vista da confiabilidade.

Outras dicas

Eu usei os observadores do sistema de arquivos de C # um número de vezes. A primeira vez que eu usei-los, tive problemas com eles parar de trabalho, principalmente devido ao fato de que eu estava processando as mudanças no segmento que relatou a mudança.

Agora, no entanto, eu só empurrar a mudança em uma fila e processar a fila em outro segmento. Isso parece resolver o problema que eu tinha originalmente. Para o seu problema, você pode ter vários observadores empurrando para a mesma fila.

No entanto, eu não usei isso com o seu tipo de escala de problema.

Na minha experiência, uma FSW não cria tráfego de rede alta. No entanto, se há um problema de desempenho, a sua abordagem de usar vários observadores e dividi-lo para menos pastas sendo vigiado sons razoável.

Eu tive algumas grandes problemas com FSW em unidades de rede, no entanto: A exclusão de um arquivo sempre jogou o evento de erro, nunca mais o evento que foi excluído. Eu não encontrar uma solução, então eu agora evitar o uso de FSW se existe uma maneira de contornar isso ...

O MSDN documentação indica que você pode usar o componente FileSystemWatcher para assistir sistema de arquivos muda em uma rede unidade .

Ele também indica que as escutas componentes observador para notificações de alteração do sistema de arquivos em vez de interrogar periodicamente a unidade de destino para mudanças.

Com base em que a quantidade de tráfego de rede depende inteiramente de quanto você espera que o conteúdo dessa unidade de rede para a mudança. O componente FSW não vai acrescentar ao nível de tráfego de rede.

Watcher parece 100% confiável - basta ver o tamanho do buffer no objeto observador. Eu testei milhares de arquivos atualizações, nenhum perdido.

Eu recomendo usar uma abordagem multi-threaded - O gatilho ser o observador de arquivo. Ele pode lançar uma linha para cada arquivo de mudanças detectadas. O observador pode processar muito mais rápido com menos chance de estouro. (Uso assíncrono segmento)

Depois de usar System.IO.FileSystemWatcher por algum tempo. Não é suficiente estável para manipular eventos que está chegando muito rápido. Para garantir 100% de ler os arquivos. Eu uso métodos de diretório simples para pesquisar os arquivos. Depois de ler, copiar imediatamente os arquivos para outra pasta. Isolá-lo a partir de novos arquivos que estão sendo adicionados enquanto você está lendo os arquivos.

Temporizador é usado para ler regularmente a pasta. Copiando o arquivo já ler a pasta de arquivo, este se certificar de que não vai ser lido novamente. A leitura subseqüente será sempre novos arquivos.

var fileNames = Directory.GetFiles(srcFolder);
foreach (string fileName in fileNames)
{
   string[] lines = File.ReadAllLines(fileName);
}

Eu não penso que haja qualquer tipo de estado ativo ou comunicação entre o computador com o FSW eo computador cuja localização está sendo monitorado. Em outras palavras, o FSW não está ping o sistema operacional de rede para verificar o arquivo.

Alguém poderia imaginar que uma mensagem ou evento é única levantado / enviado para o FSW rede quando ocorre uma alteração.

Mas tudo isso é apenas especulação. :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top