Mutexクラスを使うことにより、同時に1つの処理のみが動作するように排他制御することができる。 Mutexクラスでは名前付きミューテックスを作成することができ、ミューテックスをプロセス間で共有できる。 そのため、名前付きミューテックスを使った排他制御を行うことでアプリケーションの多重起動を抑止できる。
Mutexクラスでは、コンストラクタに適切な文字列を指定することにより名前付きミューテックスを作成することができる。 指定する文字列にはApplication.ProductNameや、あらかじめ用意したGUIDなど、他のアプリケーションが使用していない文字列を選択する。
using System;
using System.Threading;
class Sample {
static void Main()
{
// 名前付きミューテックスに与える名前
const string mutexName = "MyApplication";
// 初期所有権は与えず、名前付きミューテックスを作成
using (var mutex = new Mutex(false, mutexName)) {
// ミューテックスに入る
// (すでに他のプロセスがミューテックスの排他区間に入っている場合でも、待機せず即座に処理を返す)
if (mutex.WaitOne(0, false)) {
// ミューテックスに入った
// (このプロセス以外にミューテックスの排他区間に入っているプロセスはない)
Console.WriteLine("起動します");
// 以下、アプリケーションの処理を続行する
//Application.Run(new Form1());
Thread.Sleep(3000);
Console.WriteLine("終了しました");
}
else {
// ミューテックスに入れなかった
// (このプロセス以外にミューテックスの排他区間に入っているプロセスがある)
Console.WriteLine("既に起動しています");
}
}
}
}
Imports System
Imports System.Threading
Class Sample
Shared Sub Main()
' 名前付きミューテックスに与える名前
Const mutexName As String = "MyApplication"
' 初期所有権は与えず、名前付きミューテックスを作成
Using mutex As New Mutex(False, mutexName)
' ミューテックスに入る
' (すでに他のプロセスがミューテックスの排他区間に入っている場合でも、待機せず即座に処理を返す)
If mutex.WaitOne(0, False) Then
' ミューテックスに入った
' (このプロセス以外にミューテックスの排他区間に入っているプロセスはない)
Console.WriteLine("起動します")
' 以下、アプリケーションの処理を続行する
'Application.Run(New Form1())
Thread.Sleep(3000)
Console.WriteLine("終了しました")
Else
' ミューテックスに入れなかった
' (このプロセス以外にミューテックスの排他区間に入っているプロセスがある)
Console.WriteLine("既に起動しています")
End If
End Using
End Sub
End Class
Windows + .NET Frameworkでの動作結果例
>csc test.cs >test.exe >&2 | test.exe >&2 | test.exe >&2 | test.exe >&2 | test.exe 起動します 既に起動しています 既に起動しています 既に起動しています 既に起動しています 終了しました
Monoでは、環境変数MONO_ENABLE_SHMをセットして共有メモリの使用を有効にしないと名前付きミューテックスを使用できない。
Linux + Monoでの動作結果例
$ mcs test.cs && for i in `seq 1 5` ; do MONO_ENABLE_SHM=1 mono test.exe & done 起動します 既に起動しています 既に起動しています 既に起動しています 既に起動しています 終了しました