【发布时间】:2014-08-18 06:49:03
【问题描述】:
我已经编写了下一个通过MUTEX 防止多实例化的代码,但我想通过允许设置允许的最大实例数来扩展它的功能,所以我应该可以决定是否只允许单个实例或只有 3 个实例的多实例(例如)。
我试图弄清楚如何计算进程的互斥量,但我没有找到任何相关信息。
另一方面,我在 StackOverflow 中找到了很多帖子,解释如何通过文件名计算进程数量,我对这些都不感兴趣,因为我选择了 MUTEX 检测对我来说更安全。
有人能帮我这个心血来潮吗?
这就是我所做的一切:
Namespace My
Partial Friend Class MyApplication
#Region " Properties "
''' <summary>
''' Gets the current process mutex identifier.
''' </summary>
''' <value>The current process mutex identifier.</value>
''' <exception cref="System.FormatException">The specified value is not a valid GUID format.</exception>
Private ReadOnly Property MutexID As String
Get
' Define a Golabl Unique Identifier to name the Mutex.
Dim Id As String = "b045ce40-2863-4ce7-a7df-8afca8214454"
If Guid.TryParse(input:=Id, result:=New Guid) Then
Return Id
Else
Throw New FormatException("The specified value is not in a valid GUID format.")
End If
End Get
End Property
''' <summary>
''' Gets the maximum instances allowed for this process.
''' </summary>
''' <value>The maximum instances allowed for this process.</value>
Private ReadOnly Property MaxInstances As Integer
Get
Return 2
End Get
End Property
#End Region
#Region " Private Methods "
''' <summary>
''' Determines whether this is the unique instance that is running for this process.
''' </summary>
''' <returns><c>true</c> if this is the unique instance; otherwise, <c>false</c>.</returns>
Private Function IsUniqueInstance() As Boolean
Dim mtx As Threading.Mutex = Nothing
Try
mtx = Threading.Mutex.OpenExisting(name:=Me.MutexID)
mtx.Close()
mtx = Nothing
Catch
mtx = New Threading.Mutex(initiallyOwned:=True, name:=Me.MutexID)
End Try
Return mtx IsNot Nothing
End Function
#End Region
#Region " Event-Handlers "
''' <summary>
''' This occurs when the application starts, before the startup Form is created.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="ApplicationServices.StartupEventArgs"/> instance containing the event data.</param>
Private Sub MyApplication_Startup(ByVal sender As Object, ByVal e As ApplicationServices.StartupEventArgs) _
Handles Me.Startup
' If there is more than one instance running of this process with the same mutex then...
If Not Me.IsUniqueInstance Then ' Prevent multi-instancing.
MessageBox.Show("This is a limited demo, to run multiple instances please purchase the program.",
Application.Info.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
' Cancel the application execution.
e.Cancel = True
End If
End Sub
#End Region
End Class ' MyApplication
End Namespace
更新
这是我正在尝试的代码,我在应用程序事件、表单构造函数、加载和显示事件中都尝试过,但未检测到多实例。
Private Sub test() Handles Me.Startup
Using semaphore As New Semaphore(3I, 3I, "something")
If Not semaphore.WaitOne(100I) Then
MsgBox("Already max instances running")
End
Else
MsgBox("test")
End If
End Using
End Sub
【问题讨论】:
-
您需要
Semaphore而不是Mutex -
Already max instances running消息框你看到了什么? -
不,我总是收到“测试”消息
-
我理解这个问题。您应该删除该 using 语句。您需要将
semaphore变量作为实例变量而不是局部变量。当您的应用程序结束时Dispose它。我使用了using语句,因为它是Main方法。那么这应该可以工作。 -
不,它与
Semaphore没有任何关系,除非您的线程使用此信号量实例并调用semaphore.WaitOne。您的信号量实例应该不受任何其他线程的影响。另请注意,您不应多次调用test方法。多次调用此方法会让人觉得有多个进程正在运行,即使它们没有运行。
标签: .net vb.net winforms mutex single-instance