0

基于这个问题,我决定根据 Jim Mischel 的建议尝试使用 waithandles/eventwaithandle 作为我的解决方案。我“几乎”让它工作。这是代码

Private Sub InitDeploymentCheck()
moDeploymentCheck = New TRS.Deployment.TRSDeploymentCheck(EnvironmentVariables.Environment, AppDomain.CurrentDomain.BaseDirectory.Contains("bin"), MDIMain)
AddHandler moDeploymentCheck.DeploymentNeeded,
    Sub()
        moTimer = New System.Windows.Forms.Timer()
        moTimer.Interval = 300000 '5 minutes
        moTimer.Enabled = True
        AddHandler moTimer.Tick,
            Sub()
                'check to see if the message box exist or not before throwing up a new one

                'check to see if the wait handle is non signaled, which means you shouldn't display the message box
                If waitHandle.WaitOne(0) Then
                    'set handle to nonsignaled
                    waitHandle.Reset()
                    MessageBox.Show(MDIMain, "There is a recent critical deployment, please re-deploy STAR to get latest changes.", "Critical Deployment", MessageBoxButtons.OK, MessageBoxIcon.Warning)
                    'set the handle to signaled
                    waitHandle.Set()
                End If


            End Sub
        waitHandle.Set()
        MessageBox.Show(MDIMain, "There is a recent critical deployment, please re-deploy STAR to get latest changes.", "Critical Deployment", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    End Sub
End Sub

同样,这来自几乎我们所有应用程序都继承自的基本形式。当我们使用单个应用程序时,它可以完美运行。如果您运行多个从基本表单继承的应用程序并且有人仅单击一个消息框,则有时会在另一个应用程序中显示第二个消息框。我最初将等待句柄声明为静态/共享,并认为这是问题所在,但事实并非如此。我还尝试让每个应用程序创建自己的等待句柄并将其传递给基础,并产生相同的效果。有谁知道为什么看起来等待句柄在不同的应用程序之间共享?哦对了,waitHandle其实是一个ManualResetEvent

4

2 回答 2

1

首先,如果你想在多个应用程序中使用它,你必须EventWaitHandle使用这个构造函数创建一个命名对象,或者创建一个命名对象。AManualResetEvent仅适用于单个进程。

其次,命名Mutex可能是更好的解决方案。我刚刚意识到我推荐的代码有竞争条件。如果线程 A 执行WaitOne(0)并成功,然后线程 B 出现并在线程 A 调用之前执行相同的操作Reset,则两个线程最终都会显示消息框。

使用MutexandWaitOne(0)将解决该问题。一定要释放Mutex,但是:

if (mutex.WaitOne(0))
{
    try
    {
        // do stuff
    }
    finally
    {
        mutex.ReleaseMutex();
    }
}
于 2012-12-04T05:34:25.927 回答
0

它无法正常工作的原因是我有一个错误,我在计时器事件之外显示第一个消息框。它应该是:

waitHandle.Reset()
MessageBox.Show(MDIMain, "There is a recent critical deployment, please re-deploy STAR to get latest changes.", "Critical Deployment", MessageBoxButtons.OK, MessageBoxIcon.Warning)
waitHandle.Set()
于 2012-12-05T15:04:20.503 回答