C# - Usando WaitForChanged para receber notificações
Hoje veremos como receber notificações de eventos em operações com o sistema de arquivos de forma síncrona na linguagem C#. |
Vamos supor que você precisa ser notificado quando um determinado evento ocorrer no seu sistema de arquivos, seriam eventos como o renomear um arquivo ou diretório, aumentar ou diminuir o tamanho de um arquivo, excluir um arquivo ou diretório, criar um arquivo ou diretório, ou mesmo a alteração dos atributos de um arquivo ou diretório.
Ocorre que esta notificação deve ocorrer síncrona, ou seja, a sua aplicação não pode continuar a execução a menos que uma ação específica ocorrer em um arquivo ou diretório.
Como você faria para receber esta notificação de forma síncrona ?
Para este cenário específico temos a classe FileSystemWatcher e nesta classe o método WaitForChanged que pode ser chamado para esperar de forma síncrona a notificação de um evento.
A sintaxe mais usada é a sobrecarga : WaitForChanged(WatcherChangeTypes, Int32)
Que retorna uma estrutura que contém informações específicas sobre a alteração ocorrida, considerando o tipo de alteração que você deseja monitorar e o tempo (em milissegundos) de espera antes do tempo limite.
Esse método aguarda até que ocorra uma alteração ou tenha atingido o tempo limite. Um valor de -1 para o parâmetro timeout significa aguardar indefinidamente.
O retorno deste método é um tipo WaitForChangeResult que contém informações especificas sobre a alteração ocorrida.
Exemplo:
static void EsperarPelaAcao(FileSystemWatcher watcher) { Console.WriteLine("Aguardando 10 segundos para que o arquivo seja criado"); WaitForChangedResult resultado = watcher.WaitForChanged(WatcherChangeTypes.Created, 10000); if (resultado.TimedOut)
|
O segundo
parâmetro opcional para o método WaitForChanged
especifica o tempo em milissegundos de espera antes que a solicitação expire.
Tenha cuidado ao usar o método WaitForChanged na thread principal de um programa
Console ou na thread de interface do
usuário de um aplicativo Windows Forms. Como esse método é bloqueado até que a
alteração ocorra ou o valor de tempo limite seja atingido, nenhum outro
processamento ocorrerá na thread que o chama. Em um aplicativo Windows Forms, a interface do usuário não responderá se essa chamada ocorrer no thread
de interface do usuário em vez de em um thread de trabalho.
Criando um arquivo e aguardando a notificação
Como exemplo prático veremos um programa Console onde o método AguardaCriacaoArquivo(caminho, arquivo) recebe o caminho para criar o arquivo e o nome do arquivo.
A seguir usaremos o método WaitForChanged(WatcherChangeTypes.Created, 10000); onde vamos esperar 10 segundos para receber a notificação exibindo o resultado.
using System; using System.IO; using System.Threading; using System.Threading.Tasks;
namespace CShp_WaitForChanged Console.WriteLine("Criando arquivo ZIP... Aguarde..."); if (string.IsNullOrWhiteSpace(nomeArquivo)) FileSystemWatcher fsw = null; try fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite Task work = Task.Run(() => |
Resultado:
O método WaitForChanged retorna uma estrutura WaitForChangedResult que contém as propriedades listadas abaixo:
Propriedade | Descrição |
ChangeType | Lista o
tipo de mudança que ocorreu. Essa alteração é retornada como uma
enumeração WatcherChangeTypes. Os valores desta enumeração podem possivelmente ser combinados com OR. |
Name | Contém o nome do arquivo ou diretório que foi alterado. Se o arquivo ou diretório foi renomeado, esta propriedade retorna o nome alterado. Seu valor é definido como nulo se a chamada do método de operação atingir o tempo limite. |
OldName | O nome original do arquivo ou diretório modificado. Se este arquivo ou diretório não foi renomeado, esta propriedade irá retorna o mesmo valor da propriedade Name. Seu valor é definido como nulo se a chamada do método de operação atingir o tempo limite. |
TimedOut | Contém um booleano indicando se o método WaitForChanged atingiu o tempo limite (verdadeiro) ou não (falso) |
A enumeração NotifyFilters permite que você especifique os tipos de arquivos ou pastas para observar, conforme mostrado a seguir:
Valor | Definição |
FileName | Nome do arquivo |
DirectoryName | Nome do diretório |
Attributes | Atributos dos arquivos/diretórios |
Size | Tamanho do arquivo/diretório |
LastWrite | Última data da escrita no arquivo ou diretório |
LastAccess | Última vez que o arquivo ou pasta foi aberto |
CreationTime | A hora da criação do arquivo/diretório |
Security | As configurações de segurança |
Pegue o código do projeto aqui: CShp_WaitForChanged.zip
"Vigiai, estai firmes na fé; portai-vos varonilmente, e
fortalecei-vos.
Todas as vossas coisas sejam feitas com amor."
1 Coríntios 16:13,14
Referências:
C# - Obtendo a data e a hora por TimeZone
C# - O Struct Guid - Macoratti.net
C# - Checando Null de uma forma mais elegante e concisa
DateTime - Macoratti.net
Null o que é isso ? - Macoratti.net
Formatação de data e hora para uma cultura ...
C# - Calculando a diferença entre duas datas
NET - Padrão de Projeto - Null Object Pattern
C# - Fundamentos : Definindo DateTime como Null ...
C# - Os tipos Nullable (Tipos Anuláveis)