C# 互斥不能正常工作

C# 互斥不能正常工作,c#,mutex,C#,Mutex,所以这段代码在program.cs中,应该检查连接是否可用,以及是否有另一个实例正在运行。如果有,消息框会通知用户,并询问用户是否确定要打开应用程序。下一个问题是: 我打开应用程序,然后再次打开,消息框显示,但什么也没发生。我重复这个过程,只有在4-5次后它才能工作。然后,如果我再次打开,它将打开两个实例 static void Main() { Application.EnableVisualStyles(); Application.SetCompa

所以这段代码在program.cs中,应该检查连接是否可用,以及是否有另一个实例正在运行。如果有,消息框会通知用户,并询问用户是否确定要打开应用程序。下一个问题是: 我打开应用程序,然后再次打开,消息框显示,但什么也没发生。我重复这个过程,只有在4-5次后它才能工作。然后,如果我再次打开,它将打开两个实例

static void Main()
    { 
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        SqlConnection con123 = new SqlConnection(con123.Metoda());
        Mutex mut = null;
        try
        {
            mut = Mutex.OpenExisting("Tray minimizer");
        }
        catch
        {

        }

        if (mut == null)
        {

            mut = new Mutex(true, "Tray minimizer");
            Application.Run(new Form1());

            //Tell GC not to destroy mutex until the application is running and
            //release the mutex when application exits.
            GC.KeepAlive(mut);
            mut.ReleaseMutex();
        }
        else
        {
            //The mutex existed so exit
            mut.Close();


                DialogResult result = MessageBox.Show("AApplication is already working!Do you want to reopen it?", "Caution!", MessageBoxButtons.OKCancel);

                if (result == DialogResult.OK)
                {


                    foreach (Process p in System.Diagnostics.Process.GetProcessesByName("Name of application"))
                    {
                        try
                        {

                            p.Kill();
                          //  p.WaitForExit(); // possibly with a timeout

                            Application.Run(new Form1());
                        }
                        catch (Win32Exception winException)
                        {
                            // process was terminating or can't be terminated - deal with it
                        }
                        catch (InvalidOperationException invalidException)
                        {
                            // process has already exited - might be able to let this one go
                        }
                    }

                }
                //if (result == DialogResult.Cancel)
                //{


                //}

            }

            try
            {
                con123.Open();
                con123.Close();
            }
            catch
            {

                MessageBox.Show("Cant connect to server!!!", "Error!");
                Application.Exit();
            }

我会做一些更像:

bool mutexCreated = true;
using (Mutex mutex = new Mutex(true, "eCS", out mutexCreated))
{
    if (mutexCreated)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        SqlConnection con123 = new SqlConnection(con123.Metoda());

        Application.Run(new Form1());
    }
    else
    {
        DialogResult result = 
            MessageBox.Show("AApplication is already working!Do you want to reopen it?", "Caution!",
                                                MessageBoxButtons.OKCancel);

        if (result == DialogResult.OK)
        {
            foreach (Process p in System.Diagnostics.Process.GetProcessesByName("Name of application"))
            {
                try
                {
                    p.Kill();

                    Application.Run(new Form1());
                }
                catch (Win32Exception winException)
                {
                    // process was terminating or can't be terminated - deal with it
                }
                catch (InvalidOperationException invalidException)
                {
                    // process has already exited - might be able to let this one go
                }
            }

        }
    }

    try
    {
        con123.Open();
        con123.Close();
    }
    catch
    {

        MessageBox.Show("Cant connect to server!!!", "Error!");
        Application.Exit();
    }
}
您的版本存在的问题是,可能会在不适当的时间收集互斥

  • 一旦进入“互斥存在”路径,就永远不会释放互斥。您只需关闭任何其他进程,然后再次启动应用程序,但在新应用程序结束时,绝不提供释放互斥锁的方法

  • 您正在
    foreach(Process)
    循环中启动应用程序,这意味着如果有多个进程已经在运行(可能所有进程都带有消息框),您将为每个进程启动应用程序

  • 这也意味着,如果你没有找到另一个进程来终止,你就不会启动你的应用程序

  • 您的
    else
    案例应该类似于以下伪代码:

    dialogResult = MessageBox(...);
    if (dialogResult == OK)
    {
        foreach (var p in ...)
        {
            // Todo: make sure you do not kill the current process!
            p.Kill();
        }
    
        // now run the application
        Application.Run(new Form1());
        // now release the mutex
        mut.Release();
    }
    else
    {
        mut.Close();
    }
    

    该伪代码仍然需要一些异常处理,以确保在发生异常时正确释放互斥锁。

    这能解决您的问题吗?我没有使用
    OpenExisting
    ,它没有文档保证在失败时返回
    null
    ,而是使用
    Mutex
    构造函数,该构造函数将
    输出bool
    ,以确定互斥体是创建的还是已经存在。启动应用程序并对其执行任何操作(根据我看到的部分猜测)都会移动到与创建互斥锁或关闭现有实例相关的所有操作下方

    现在的步骤如下:

  • runApp
    变量初始化为true
  • 尝试创建
    Mutex
  • 检查是否创建了互斥锁(不存在)
    • 如果未创建
      互斥体,则该互斥体已存在
      
      • 询问用户是否要退出,等待互斥锁可用(表示已完成强制退出现有应用程序实例)
      • 如果他们不想退出,请将
        runApp
        设置为
        false
  • 检查
    runApp
    标志是否仍然为真

    • 如果为true,则运行应用程序。返回后(表单退出),尝试连接

      注意,这可能有一个错误,我不知道你是否打算阻止,因为你在应用程序中

  • 释放互斥锁

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    SqlConnection con123 = new SqlConnection(con123.Metoda());
    string ProgramName = "Tray minimizer.exe";
    bool mutCreated = false;
    Mutex mut = new Mutex(true, ProgramName, out mutCreated);
    bool runApp = true;
    if (!mutCreated)
    {
        DialogResult result = MessageBox.Show("Application is already working! Do you want to reopen it?", "Caution!", MessageBoxButtons.OKCancel);
    
        if (result == DialogResult.OK)
        {
            foreach (Process p in System.Diagnostics.Process.GetProcessesByName(ProgramName))
            {
                try
                {
                    p.Kill();
                }
                catch { }
            }
            mut.WaitOne(); // Wait for ownership of the mutex to be released when the OS cleans up after the process being killed
        }
        else
        {
            runApp = false;
        }
    }
    
    if (runApp)
    {
        Application.Run(new Form1());
    
        try
        {
            con123.Open();
            con123.Close();
        }
        catch
        {
    
            MessageBox.Show("Cant connect to server!!!", "Error!");
            Application.Exit();
        }
    
        mut.ReleaseMutex();
    }
    

  • 好的,那么你的问题是什么?到目前为止,你已经讲了一个故事,但你还没有问任何问题。我会将这些异常记录在某个地方,如果你有如此多的空捕捉,那么你可能会在某个地方遇到异常。它工作不正常,我的意思是它不一致。它每五次工作一次,我不知道为什么。Kevin我这么做了,它什么也抓不到。首先,你一定要清理你的代码,清除所有空的
    catch
    es,并正确处理异常。