【发布时间】:2015-09-04 03:06:58
【问题描述】:
我的 Windows 窗体应用程序中有以下程序流程(不幸的是,WPF 不是一个可行的选择):
- GUI 线程创建一个启动屏幕和一个相当空的主窗口,两者都继承
Form。 - 初始屏幕显示并提供给
Application.Run()。 - 初始屏幕将发送一个触发
async事件处理程序的事件,该事件处理程序执行初始化,使用IProgress接口向GUI 报告进度。 (这完美无缺。) - 在初始化过程中的某个时刻,我需要根据某些插件提供的信息动态创建 GUI 组件并将它们添加到主窗口。
此时我被卡住了:我知道我需要让 GUI 线程为我创建这些组件,但是没有 Control 我可以调用 InvokeRequired。执行 MainWindow.InvokeRequired 均无效。
我能想到的唯一想法是触发一个连接到 GUI 线程中的工厂的事件,然后等待该工厂触发另一个提供所创建控件的事件。但是我很确定有一个更强大的解决方案。有谁知道如何做到这一点?
【问题讨论】:
-
好吧,您需要在 GUI 线程上完成所有这些工作 - 那么为什么不准备所有信息以在单独的线程上实际构建 GUI,然后将所有信息传递回启动画面作为成功价值?无论如何,GUI 将在那个时候被阻止。
-
例如,只需在面板中创建所有控件,完成后传递单个 GUI 元素并将其添加到表单中。
-
但是,您实际上有一个 GUI。使用闪屏的 Begin/Invoke() 方法同样有效。通过复制 SynchronizationContext.Current 并在线程中使用其 Post 方法,您将获得一些优雅点。或者按预期使用异步,延续应该在 GUI 线程上运行。
-
@HansPassant 感谢您评论的最后一部分,它导致了(我认为)一个相当优雅的解决方案,它将启动屏幕与任何初始化任务完全分离。如果您对更多详细信息感兴趣,请查看我的回答。
标签: c# multithreading winforms async-await