トップ回答者
【C#】MutexのWaitOne()について

質問
-
アプリケーションの多重起動防止のために、下記のようにMutexを使っています。
-----------------------------------------------------------------
namespace WpfApplication1
{
public partial class App : Application
{
private static System.Threading.Mutex mutex;
private void Application_Startup(object sender, StartupEventArgs e)
{
/* Mutexを生成 */
mutex = new System.Threading.Mutex(false, "App_Mutex");
/* 二重起動をチェック */
if ( mutex.WaitOne(0, false) != true)
{
/* 二重起動の場合はエラーを表示して終了 */
MessageBox.Show("すでに起動されています");
/* Mutexを破棄 */
mutex.Close();
mutex = null;
/* 起動を中止してプログラムを終了 */
this.Shutdown();
}以下処理
}
private void Application_Exit(object sender, ExitEventArgs e)
{
if (mutex != null)
{
/* Mutexを解放 */
mutex.ReleaseMutex();
/* Mutexを破棄 */
mutex.Close();
}
}
}
}-----------------------------------------------------------------
Debugモードでビルドして、「デバッグ開始(F5)」で実行すると、問題は無いのですが、
同じDebugモードのまま、「デバッグなしで開始(Ctrl+F5)」で実行すると、
mutex.WaitOne(0, false)の戻り値がfalseとなり、多重起動していると判断されます。
また、Mutex生成前に1秒待つ(System.Threading.Thread.Sleep(1000))と
両方の実行で、mutex.WaitOne(0, false)の戻り値がtrueとなり正常に判定されます。
※二つ目のExeを実行するとちゃんと多重起動防止が働きます。
この現象は何故起きるのでしょうか。
ご存知の方いらっしゃいましたら、ご教授ください。
- 移動 星 睦美 2015年7月21日 0:58 Windows クライアント開発 から
回答
すべての返信
-
Mutexの使い方が根本的に間違っています。
new Mutex(false, "App_Mutex"); はマシン内で1度しか実行できません。既にMutexが作成済みの場合は後から実行した側が失敗します。後から実行する側はMutex.OpenExisting()を使います。(この時点で先に起動しているアプリケーションが存在することが分かってしまうわけですが…)
# タイトルに 【C#】 などと付けるぐらいなら初めからC#フォーラムを選択すべきです。モデレーターさん移動をお願いします。- 編集済み 佐祐理 2015年7月17日 0:15
-
// 質問の回答ではありません。
new Mutex(false, "App_Mutex"); はマシン内で1度しか実行できません。既にMutexが作成済みの場合は後から実行した側が失敗します。
いいえ、そんなことはありません。同じ名前のミューテックスを複数newできます。存在していなければ作られますし、存在していれば既存のを開きます(アクセス制御による権限違いで失敗とかのケースはありますが)。
これはWindows APIのCreateMutex関数でも同じです。
本題とは関係ないですが、Mutex.WaitOneを呼び出す際は、AbandonedMutexExceptionを処理しておいた方が良いです。前のプロセスが強制終了してReleaseMutexが呼ばれていなかった際に、後続のプロセスで発生し得ます。