Last active
August 14, 2020 03:44
-
-
Save in-async/fc26db116ba32f617e15931680bda383 to your computer and use it in GitHub Desktop.
アプリケーション単位の排他制御を行う .NET クラス。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using System.Runtime.InteropServices; | |
using System.Threading; | |
namespace InAsync.Threading { | |
/// <summary> | |
/// アプリケーション単位の排他制御を行うクラス。 | |
/// </summary> | |
public static class ApplicationLock { | |
/// <summary> | |
/// アプリケーション毎に一意の <see cref="Guid"/>。 | |
/// </summary> | |
/// <remarks> | |
/// アプリケーションの <see cref="Guid"/> の取得については下記を参考にした。 | |
/// https://stackoverflow.com/questions/502303/how-do-i-programmatically-get-the-guid-of-an-application-in-net2-0/11486085#11486085 | |
/// </remarks> | |
private static readonly Guid _appGuid = Marshal.GetTypeLibGuidForAssembly(Assembly.GetExecutingAssembly()); | |
/// <summary> | |
/// 排他制御のキーとなるシステムミューテックス名。 | |
/// </summary> | |
/// <remarks> | |
/// Global プリフィクスについては下記を参照。 | |
/// https://dobon.net/vb/dotnet/process/checkprevinstance.html#section2 | |
/// </remarks> | |
private static readonly string _mutexName = $@"Global\{{{_appGuid}}}"; | |
/// <summary> | |
/// プロセス間の排他制御を行う為の <see cref="Mutex"/> オブジェクト。 | |
/// </summary> | |
/// <remarks> | |
/// アプリケーション終了時にファイナライザーによって自動的に <c>Dispose</c> されるので、明示的に <c>Close</c> しなくても良い。 | |
/// </remarks> | |
private static Mutex _mutex; | |
/// <summary> | |
/// クリティカルセクションへの入場権の取得を試みます。 | |
/// </summary> | |
/// <returns>クリティカルセクションへの入場権を取得できれば <c>true</c>、それ以外なら <c>false</c>。</returns> | |
public static bool TryEnter() { | |
// 既に排他制御されているか否かは、システムミューテックスを新規作成できるか否かで判定する。 | |
// システムミューテックスを新規に作成できれば、_mutexName に対する排他制御が行われていないと判定できる。 | |
// システムミューテックスは全てのハンドルが閉じられた時点で自動的に破棄される(https://msdn.microsoft.com/ja-jp/library/cc429275.aspx)。 | |
// _mutex はシステムミューテックスのハンドルを保持している為、アプリケーション終了時に Close 又は Dispose する必要がある。 | |
// 一方で、Mutex (厳密には SafeHandle) はファイナライザーを実装している為、アプリケーション終了時に自動的に Dispose される。 | |
_mutex = new Mutex(false, _mutexName, out var createdNew); | |
if (createdNew == false) { | |
_mutex.Close(); | |
_mutex = null; | |
} | |
return createdNew; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Process
を使った多重起動禁止コードを一行変えるだけで、Mutex
による多重起動禁止が可能になります!Before
After