Recentemente, estou trabalhando em um ConsoleApp para agendamento de trabalhos. Este artigo não discutirá a parte de agendamento de trabalhos por enquanto (escreverei sobre isso mais tarde).
Requisitos de execução do ConsoleApp
1. Inicie o aplicativo quando o sistema for iniciado;
2. Instância única em execução em cada sessão;
Ao abrir um link de área de trabalho remota, apenas uma instância do ConsoleApp poderá ser iniciada.
3. Apenas uma instância pode ser executada no sistema;
Quando vários links de área de trabalho remota são abertos, apenas uma instância do ConsoleApp pode ser iniciada.
Mutex
Mutex: Uma primitiva de sincronização que também pode ser usada para sincronização entre processos.
MSND visível: http://msdn.microsoft.com/zh-cn/library/system.threading.mutex.aspx
Na introdução do documento oficial, consta este parágrafo
Em um servidor que executa os Serviços de Terminal, um mutex de sistema nomeado pode ter dois níveis de visibilidade. Se o nome começar com o prefixo "Global", o mutex ficará visível em todas as sessões do servidor de terminal. Se o nome começar com o prefixo "Local", o mutex só será visível na sessão do terminal server em que foi criado. Nesse caso, você pode ter um mutex separado com o mesmo nome em todas as outras sessões do servidor de terminal no servidor. Se um mutex nomeado for criado sem especificar um prefixo, ele usará o prefixo "Local". Em uma sessão do terminal server, dois mutexes que diferem apenas no prefixo do nome são mutexes independentes e esses dois mutexes são visíveis para todos os processos na sessão do terminal server. Ou seja: os nomes de prefixo "Global" e "Local" indicam o escopo do nome mutex relativo à sessão do terminal server (não relativo ao processo).
Infelizmente, nenhum exemplo de C# foi encontrado. Esta passagem pode ser entendida como:
mutexName= "Local\" +"NomeAplicativo";
É válido apenas para a sessão em que foi criado, o que significa que quando uma nova conexão remota for aberta, a instância do ConsoleApp será reiniciada.
mutexName= "Global\" +"NomeAplicativo";
Válido para todas as sessões Quando vários links remotos são abertos, somente o primeiro link remoto iniciará com êxito a instância do ConsoleApp.
Execute como uma única instância por sessão
vazio estático privado LocalMutex()
{
//Se deseja criar mutex pela primeira vez
bool novoMutexCreated = false;
string mutexName = "Local\" + "tenghoo";
Mutex mutex = nulo;
tentar
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
pegar (exceção ex)
{
Console.Write(ex.Mensagem);
System.Threading.Thread.Sleep(3000);
Ambiente.Exit(1);
}
// Cria mutex pela primeira vez
if (novoMutexCriado)
{
Console.WriteLine("Programa iniciado");
//todo: Aqui está a tarefa a ser executada
}
outro
{
Console.Write("Outra janela já está em execução e será fechada automaticamente após 3 segundos...");
System.Threading.Thread.Sleep(1000);
Console.Write("1");
System.Threading.Thread.Sleep(1000);
Console.Write("2");
System.Threading.Thread.Sleep(1000);
Console.Write("3");
Environment.Exit(1);//Sai do programa
}
}
Operação de instância única em todo o sistema
vazio estático privado GlobalMutex()
{
//Se deseja criar mutex pela primeira vez
bool novoMutexCreated = false;
string mutexName = "Global\" + "tenghoo";
Mutex mutex = nulo;
tentar
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
pegar (exceção ex)
{
Console.Write(ex.Mensagem);
System.Threading.Thread.Sleep(3000);
Ambiente.Exit(1);
}
// Cria mutex pela primeira vez
if (novoMutexCriado)
{
Console.WriteLine("Programa iniciado");
//todo: Aqui está a tarefa a ser executada
}
outro
{
Console.Write("Outra janela já está em execução e será fechada automaticamente após 3 segundos...");
System.Threading.Thread.Sleep(1000);
Console.Write("1");
System.Threading.Thread.Sleep(1000);
Console.Write("2");
System.Threading.Thread.Sleep(1000);
Console.Write("3");
Environment.Exit(1);//Sai do programa
}