0

我试图找出在使用双显示器的 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();
    }
}

在这个调用上让主线程阻塞感觉有点乱WaitForAllDisplays(),但我一直想不出更好的方法来做到这一点。注意Form1Form2是相互独立的,从不直接通信。

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

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

4

1 回答 1

1

起初我认为这会起作用:

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

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

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

笔记:

  1. AbandonedMutexException 是 .NET Framework 2.0 版中的新增功能。在以前的版本中,当互斥体被放弃时,WaitAll 方法返回 true。废弃的互斥锁表示严重的编码错误。异常包含对调试有用的信息。
  2. 在 Windows 98 或 Windows Millennium Edition 上不会引发此异常。
于 2009-11-11T04:52:28.493 回答