gpt4 book ai didi

c# - 从控制台调用的 Form.Show() 会卡住 GUI

转载 作者:太空狗 更新时间:2023-10-29 21:05:54 27 4
gpt4 key购买 nike

我正在尝试直接从控制台应用程序实例化一个表单。
出于某种奇怪的原因,当我调用 Form1.Show() 时,新创建的 Form 不会绘制其所有控件并卡住(HourGlass 图标)。然而,当我调用 ShowDialog() 时,一切正常,除了我需要返回控制台但我不能,所以这不是一个选项......
我应该怎么做才能使我的表单正确显示?我在这里遗漏了什么吗?

OrderControlForm OrderControlBox = new OrderControlForm();
OrderControlBox.BuyEvent += new OrderControl.BuyDelegate(doBuy);
OrderControlBox.SellEvent += new OrderControl.SellDelegate(doSell);
OrderControlBox.Show();

调用上述代码以响应控制台用户输入的命令。

编辑:这是工作代码:

        Thread mThread = new Thread(delegate()
{
StratControlBox = new StratControl(StratIDs);
StratControlBox.ShowDialog();
});

mThread.SetApartmentState(ApartmentState.STA);

mThread.Start();

我仍然不明白为什么我必须调用 ShowDialog() 而不是 Show()
当我使用后者时,表单在绘制后立即“消失”。

最佳答案

原因是因为 ShowDialog 执行它自己的消息循环,而 Show 没有。您需要调用 Application.Run,而不是调用 Show,它会执行消息循环。但是,由于它是同步循环,处理传入的窗口消息直到窗体关闭,因此实际上与调用 ShowDialog 没有什么不同。

因此,如果您想异步显示表单,则需要从另一个线程执行此操作。但是,为了安全起见,请通过调用 newThread.SetApartmentState(ApartmentState.STA); 确保新线程使用单元线程。

另外,我建议只从一个 UI 线程显示一个主窗体。如果该主窗体从它自己的线程中显示其他窗体,那很好,但是,如果您开始尝试显示多个窗体,每个窗体都从它们自己的线程中显示,则可能会导致问题。

关于您的更新

从线程调用 Show 不起作用的原因有两个。首先,它是同步的,所以直到表单关闭才返回。这很重要,因为一旦执行离开您的匿名方法,线程就会终止。因此,当您调用 Show 时,它会立即返回,然后离开您的方法从而终止线程。

其次,即使表单确实保持打开状态,它也会像以前一样没有响应,原因都是一样的。 WinForms 需要一个消息循环,不断寻找新的传入窗口消息并处理它们。消息循环调用名为 WndProc 的方法。如果没有消息循环调用 WndProc 方法来处理传入的窗口消息,窗体将完全无法响应用户。例如,当鼠标驱动程序通知 Windows 用户已按下鼠标按钮时,Windows 将向应用程序的消息队列发送一条 WM_MOUSEDOWN 消息。如果您没有在某处不断循环查看队列中是否有任何消息并对其进行操作的代码,您将永远不会得到鼠标按下事件。

正如我在上面提到的,ShowDialog 方法执行它自己的消息循环,因此它可以工作,但 Show 不会。 Show 假设它正在被一个已经运行的消息循环调用。如果出于某种原因您不想调用 ShowDialog,则可以调用 Application.Run(StratControlBox)Run 方法将为您显示表单,然后停留在消息循环中直到表单关闭。因此,它是一个同步调用,就像 ShowDialog 一样,所以您的线程在窗体关闭之前不会终止。

关于c# - 从控制台调用的 Form.Show() 会卡住 GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11420717/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com