0

したがって、このコードは program.cs にあり、接続が利用可能かどうか、および別のインスタンスが既に実行されているかどうかを確認することになっています。存在する場合は、ユーザーに通知し、アプリケーションを開きたいかどうかを確認するメッセージ ボックス。問題は次のとおりです。アプリケーションを開き、もう一度開くと、メッセージ ボックスが表示されますが、何も起こりません。私はプロセスを繰り返し、4〜5回後にのみ機能します。次に、もう一度開くと、2 つのインスタンスが開きます。

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();
            }
4

3 に答える 3

2

私はもっ​​と好きなことをします:

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();
    }
}

お使いのバージョンの問題は、mutex が不適切なタイミングで収集される可能性があることです。

于 2013-04-19T18:31:15.837 に答える
0
  1. 「ミューテックスが存在する」パスにたどり着くと、ミューテックスを解放することはありません。他のプロセスを強制終了してアプリを再度起動するだけで、新しいアプリが終了したときにミューテックスを解放する方法を提供することはありません。

  2. ループ内でアプリを起動していますforeach (Process)。つまり、複数のプロセスが既に実行されている場合 (おそらくすべてメッセージ ボックスがある場合)、それぞれに対してアプリを起動します。

  3. これは、強制終了する別のプロセスが実際に見つからない場合、アプリを起動しないことも意味します。

ケース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();
}

この疑似コードには、例外が発生した場合にミューテックスが適切に解放されるようにするための例外処理が必要です。

于 2013-04-19T18:33:51.617 に答える
0

これで問題は解決しますか? 失敗したときにOpenExisting戻るというドキュメントの保証がないを使用するのではなく、ミューテックスが作成されたかどうか、または既に存在するかどうかを判断するために を受け取るコンストラクターを使用しました。アプリケーションを起動し、それを使って何かを行うこと (私が見たものに基づいて部分的に推測しています) は、ミューテックスの作成または既存のインスタンスのクローズに関連するすべての下に移動されます。nullMutexout bool

手順は次のとおりです。

  1. runApp変数を true に初期化する
  2. を作成してみてくださいMutex
  3. が作成されたかどうかを確認しますMutex(まだ存在しません) 。
    • が作成されていない場合はMutex、既に存在します
      • 終了するかどうかをユーザーに尋ね、mutex が使用可能になるまで待ちます (既存のアプリケーション インスタンスの強制終了の完了を示します)。
      • 彼らが終了したくない場合は、に設定runAppしますfalse
  4. runAppフラグがまだ trueかどうかを確認する

    • true の場合は、アプリケーションを実行します。それが戻った後(フォームが終了した後)、接続を試みます

      これにはバグがある可能性があることに注意してください。アプリにいるときにブロックするつもりかどうかはわかりません。

  5. ミューテックスを解放する

    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();
    }
    
于 2013-04-19T18:34:35.010 に答える