多显示器应用程序中的表单管理

时间:2009-11-11 04:28:20

标签: c# winforms multiple-monitors

我正在尝试找出在使用双显示器的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()这个Form1电话中阻止主线程感觉有点混乱,但我还没有想到更好的方法来做到这一点。请注意,Form2和{{1}}彼此独立,从不直接沟通。

我考虑使用计数信号量等待所有显示关闭,但这与传统信号量略有相反。我不想在资源可用时执行,而是阻止直到返回所有资源。

有关更好方法的任何想法吗?

1 个答案:

答案 0 :(得分:1)

起初我认为这样可行:

您可以使用事件,例如:2个ManualResetEvent对象。 主线程将使用WaitHandle.WaitAll和2个Mutexes数组等待事件。 每个线程都获得对1事件的引用,并在它完成时(在它死亡之前)发出信号。

但后来我认为你最好不要再使用2个互斥锁并等待它们。 这样,如果一个线程异常终止而没有“发信号”(=释放互斥锁),你将得到一个AbandonedMutexException,你可以并且应该处理它。您可以使用AbandonedMutexException.MutexIndex来了解导致异常的线程。

您可以查看此answer以了解如何处理互斥锁和异常

注意:

  1. AbandonedMutexException是新的 .NET Framework 2.0版。在 以前的版本,WaitAll 当互斥锁为时,该方法返回true 弃。一个废弃的互斥体 表示严重的编码错误。 该例外包含信息 对调试很有用。
  2. 这 Windows上不会抛出异常 98或Windows Millennium Edition。