0

デュアル モニターを使用する C# アプリケーションで複数のフォームを管理する最善の方法を見つけようとしています。アプリケーションは「ランチパッド」から始まり、オペレーターに簡単な情報と「GO」ボタンを提供します。そのボタンを押すと、ランチパッドが非表示になり、各モニターにフルスクリーンでフォームが表示されます。ここで関連するコードをキャプチャしようとしました:

private static List<Thread> _displays = new List<Thread>();

// "GO" button handler
private void OnClick(Object sender, EventArgs args) {
    Launch(new Form1());
    Launch(new Form2());
    WaitForAllDisplays();
}

private static void Launch(Form form) {
    Thread thread = new Thread(LaunchDisplay);
    thread.IsBackground = true;
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start(form);
    _displays.Add(thread);
}

private static void LaunchDisplay(Object obj) {
    Form display = obj as Form;
    // [snip] logic to place form on correct monitor [/snip]
    display.ShowDialog();
}

public static void WaitForAllDisplays() {
    foreach (Thread thread in _displays) {
        thread.Join();
    }
}

このWaitForAllDisplays()呼び出しでメイン スレッドをブロックしたままにしておくのは少し面倒ですが、これを行うためのより良い方法を思いつきませんでした。Form1Form2は互いに独立しており、直接通信することはありません。

すべてのディスプレイが閉じるのを待つためにカウンティング セマフォを使用することを検討しましたが、これは従来のセマフォとは少し逆です。リソースが利用可能になったときに実行する代わりに、すべてのリソースが返されるまでブロックしたいと考えています。

より良いアプローチについて何か考えはありますか?

4

1 に答える 1

1

最初はこれがうまくいくと思いました:

たとえば、イベントを使用できます。2 つの ManualResetEvent オブジェクト。メイン スレッドは、WaitHandle.WaitAllと 2 つの Mutex の配列を使用してイベントを待機します。各スレッドは 1 つのイベントへの参照を取得し、それが完了すると (終了する前に) 通知します。

しかし、代わりに 2 つのミューテックスを使用して、それらを待機する方がよいと考えました。このようにして、スレッドが「シグナリング」(= ミューテックスの解放) なしで異常終了した場合、処理できる AbandonedMutexException が発生し、処理する必要があります。AbandonedMutexException.MutexIndex を使用して、どのスレッドが例外を引き起こしたかを知ることができます。

この回答を見て、ミューテックスと例外を処理する方法を確認できます

ノート:

  1. AbandonedMutexException は、.NET Framework バージョン 2.0 で新しく追加されました。以前のバージョンでは、mutex が破棄されると、WaitAll メソッドは true を返しました。放棄されたミューテックスは、重大なコーディング エラーを示します。例外には、デバッグに役立つ情報が含まれています。
  2. この例外は、Windows 98 または Windows Millennium Edition ではスローされません。
于 2009-11-11T04:52:28.493 に答える