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

C# 多显示应用程序中的表单管理,c#,winforms,multiple-monitors,C#,Winforms,Multiple Monitors,我试图找出在使用双监视器的C#应用程序中管理多个表单的最佳方法。应用程序启动到一个“启动板”,它只给操作员一些快速信息和一个“开始”按钮。按下该按钮将隐藏启动板,并在每个监视器上全屏显示窗体。我已尝试在此处捕获相关代码: private static List<Thread> _displays = new List<Thread>(); // "GO" button handler private void OnClick(Object sender, EventAr

我试图找出在使用双监视器的C#应用程序中管理多个表单的最佳方法。应用程序启动到一个“启动板”,它只给操作员一些快速信息和一个“开始”按钮。按下该按钮将隐藏启动板,并在每个监视器上全屏显示窗体。我已尝试在此处捕获相关代码:

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();
    }
}
private static List_displays=new List();
//“GO”按钮处理程序
私有void OnClick(对象发送方、事件args args){
发布(新表单1());
发布(新表单2());
WaitForAllDisplays();
}
专用静态无效启动(表格){
线程线程=新线程(启动显示);
thread.IsBackground=true;
SetApartmentState(ApartmentState.STA);
线程启动(表单);
_显示。添加(线程);
}
专用静态无效启动显示(对象obj){
表单显示=作为表单的obj;
//[snip]将表单放置在正确监视器上的逻辑[/snip]
display.ShowDialog();
}
公共静态void WaitForAllDisplays(){
foreach(线程在_显示){
thread.Join();
}
}
在这个
WaitForAllDisplays()
调用中,让主线程被阻塞感觉有点混乱,但我还没有想出更好的方法来实现这一点。请注意,
Form1
Form2
彼此独立,从不直接通信

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


关于更好的方法有什么想法吗?

起初,我认为这会奏效:

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

但是我想你最好使用两个互斥锁,然后等待它们。 这样,如果线程在没有发出“信号”(=释放互斥)的情况下异常终止,您将得到一个可以并且应该处理的废弃MutexException。您可以使用废弃的MutexException.MutexIndex来了解是哪个线程导致了异常

您可以看看这个,看看如何处理互斥和异常

注意:

  • 废弃mutexception在 .NETFramework版本2.0。在里面 以前的版本,WaitAll 方法在禁用互斥时返回true 被遗弃的。废弃的互斥体 表示严重的编码错误。 异常包含信息 用于调试
  • 这个 Windows上不会引发异常 98或Windows Millennium Edition

  • 这是处理互斥问题的好方法。。。最后我订阅了
    FormClosing
    事件,并保留了一个“opendialogs”计数器。我能够消除对
    WaitForAllDisplays()
    方法的需要。谢谢你的建议!