代码之家  ›  专栏  ›  技术社区  ›  jheddings

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

  •  0
  • jheddings  · 技术社区  · 15 年前

    我正在尝试找出在使用双监视器的C应用程序中管理多个表单的最佳方法。应用程序开始启动一个“LaunchPad”,它只是给操作员一些快速信息和一个“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 回复  |  直到 14 年前
        1
  •  1
  •   Community c0D3l0g1c    7 年前

    一开始我认为这是可行的:

    您可以使用事件,例如:2 ManualReseteEvent对象。 主线程将使用 WaitHandle.WaitAll 以及一个由两个互斥体组成的数组。 每个线程都会得到一个对1个事件的引用,并在完成时(死前)向它发出信号。

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

    你可以看看这个 answer 了解如何处理互斥和异常

    注:

    1. abrandonedmutexception是新的 .NET Framework 2.0版。在 以前的版本,waitall 当mutex为 被遗弃的。被抛弃的互斥体 表示严重的编码错误。 异常包含信息 用于调试。
    2. 这个 在Windows上未引发异常 98或Windows Millennium Edition。