通过计算互斥量的数量来限制最大流程实例?

时间:2014-08-18 06:49:04

标签: .net vb.net winforms mutex single-instance

我编写了下一个代码来防止通过MUTEX实现多实例化,但是我想通过允许设置允许实例的最大数量来扩展其功能,所以我应该决定是否要仅允许单个实例或仅包含3个实例的多实例(例如)。

我试图弄清楚如何计算进程的互斥量,但我没有找到任何关于。

另一方面,我在StackOverflow中发现了很多帖子,解释了如何通过它的文件名来计算进程数量,我对此没有兴趣,因为我选择了 MUTEX < / strong>检测对我来说更安全。

有人可以随心所欲地帮助我吗?。

这就是我所做的一切:

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

1 个答案:

答案 0 :(得分:4)

Mutex是互斥的。它最多只允许一个线程继续进行。如果您需要允许线程数(在这种情况下为处理),则需要Semaphore而不是互斥。

C#样本:

private static void Main()
{
    using (Semaphore semaphore = new Semaphore(3, 3, Assembly.GetExecutingAssembly().GetName().FullName))
    {
        if (!semaphore.WaitOne(100))
        {
            MessageBox.Show("Already max instances running");
            return;
        }

        //Start your application here
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

VB.Net示例:

Private Shared Sub Main()
    Using semaphore As New Semaphore(3, 3, Assembly.GetExecutingAssembly().GetName().FullName)
        If Not semaphore.WaitOne(100) Then
            MessageBox.Show("Already max instances running")
            Return
        End If

       'Start your application here
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())
    End Using
End Sub

P.S:使用http://converter.telerik.com/从C#转换为VB

的代码