C# - Apresentando a classe Mutex |
Neste artigo vou apresentar a classe Mutex, seu conceito, suas propriedades, como podemos usá-la e um exemplo prático na linguagem C#. |
O que é Mutex ? (mutex é uma forma abreviada de mutually exclusive)
A definição da MSDN (numa tradução livre by Macoratti) diz o seguinte sobre Mutex : "É um primitivo de sincronização que também pode ser usado para sincronização entre processos." (arre égua...)
fonte: https://msdn.microsoft.com/pt-br/library/system.threading.mutex%28v=vs.110%29.aspx
Na linguagem C#, Mutex é uma classe definida na livraria de classes da plataforma .NET (namespace System.Threading) que pode ser usada para prevenir a execução simultânea de um bloco de código por múltiplas threads que estão rodando em um processo único ou múltiplo.
Assim, Mutex é usado como um primitivo de sincronização em situações onde o recurso tem que ser compartilhado com múltiplas thread simultaneamente. Os objetos mutex nomeados são usados para fazer a sincronização interprocessos, porque vários aplicativos podem acessar o mesmo objeto mutex.
A classe Mutex foi projetada para proteger um recurso compartilhado, como memória, um identificador de arquivo ou uma conexão de rede de acesso simultâneo por vários segmentos ou processos.
Quando
uma ou mais threads necessitam de acesso a um recurso partilhado, ao mesmo
tempo, o sistema necessita de um mecanismo de sincronização para garantir que
apenas um segmento de cada vez utiliza o recurso.
Mutex é um primitivo de sincronização que concede acesso exclusivo para o
recurso compartilhado para apenas uma thread. Se uma thread adquire um Mutex, o
segundo segmento que quer adquirir esse Mutex é suspenso até que a primeira
thread libere o Mutex.
Isso ajuda a evitar a corrupção dos dados que pode ocorrer se não houver uma
sincronização.
Um dos seus usos mais frequentes é verificar se há uma única instância de um
aplicativo rodando ao mesmo tempo. Você pode criar objetos mutex com um
identificador único que podem ser abertos por outros processos e assim garantir
que apenas uma instância esta sendo executada no computador.
A seguir vou mostrar dois exemplos básicos de usos da classe Mutex usando o VS 2013 Community e o VS 2015 Community.
Recursos usados :
1 - Usando Mutex e verificando se mais de uma instância esta em execução
Neste exemplo vamos criar uma aplicação Console e verificar se existe um objeto Mutex criado para definir se já existe uma instância em execução.
Abra o VS Community 2013 e clique em New Project;
A seguir selecione Visual C# -> Windows -> Windows Forms Application;
Informe o nome Usando_Mutex e clique no botão OK;
Abra o arquivo Program.cs gerado no projeto e inclua o código abaixo:
using System; using System.Threading; namespace Usando_Mutex static bool IsSingleInstance() // Existe somente uma instância static void Main(string[] args) |
O método OpenExisting() da classe Mutex abre um mutex nomeado se ele já existir.
Se não existir uma instância do objeto mutex, o método gera uma exceção em vez de criar o objeto do sistema. Para criar um objeto mutex podemos usar um dos construtores Mutex.
Para testar eu vou abrir duas instâncias do Visual Studio abrindo o mesmo projeto e executar cada instância.
Na execução da primeira instância do VS temos o seguinte resultado:
Executando a segunda instância do VS obtemos o resultado abaixo:
2 - Permitindo somente uma instância em execução
Neste exemplo vamos criar uma aplicação Windows Forms e permitir somente uma instância da aplicação.
Abra o VS Community 2015 e clique em New Project;
A seguir selecione Visual C# -> Windows -> Windows Forms Application;
Informe o nome Mutex_UmaInstancia e clique no botão OK;
A partir da ToolBox inclua os seguintes controles no formulário form1.vb:
1 Label - Executar Somente Uma Instância com Mutex
Abaixo leiaute do formulário:
O projeto em si não tem importância, o que vale é mostrar a utilização da classe Mutex.
Vamos fazer isso.
Abra o arquivo Program.cs e inclua o código abaixo:
using System; using System.Threading; using System.Windows.Forms;
namespace Mutex_UmaInstancia [STAThread] try |
Usamos o método WaitOne(int32, boolean) que bloqueia a thread atual até que a instância atual recebe um sinal, usando um TimeSpan para especificar o intervalo de tempo e especificar se deseja sair do domínio de sincronização antes do tempo de espera.
O método ReleaseMutex -
Libera o Mutex. Ele será liberado quando a aplicação termina, mas mesmo se a
aplicação terminar sem liberar o Mutex ele será automaticamente liberado
pelo .NET Framework.
Para testar vamos abrir duas instâncias do VS abrindo o mesmo projeto.
Ao executar o projeto pela primeira vez teremos o seguinte resultado:
Na primeira vez temos somente uma instância em execução e aplicação é executada normalmente.
Executando a segunda instância teremos o resultado a seguir:
Na segunda execução o Mutex detecta que outra instância já esta em execução e lança a exceção que capturamos e exibimos a mensagem acima.
Como a
classe mutex é um invólucro para uma construct Win32, ela requer transições de
interoperabilidade que resultam em uma queda no desempenho.
Por este motivo, ela não é uma boa opção a menos que seu uso seja realmente
necessário.
Pegue os projetos completos aqui : Usando_Mutex.zip (VS 2013) e Mutex_UmaInstancia.zip (VS 2015)
Disse-lhe Jesus: Estou há tanto tempo
convosco, e não me tendes conhecido, Filipe? Quem me vê a mim vê o Pai; e como
dizes tu: Mostra-nos o Pai?
João 14:9
Referências:
https://msdn.microsoft.com/pt-br/library/system.threading.mutex%28v=vs.110%29.aspx
https://msdn.microsoft.com/en-us/library/windows/hardware/ff548097%28v=vs.85%29.aspx