我的目标
我想有一个主处理线程(非GUI),并能够根据需要在自己的后台线程中分离GUI,并让我的主非GUI线程继续工作。 换句话说,我希望我的主非GUI线程成为GUI线程的所有者,反之亦然。 我不确定Windows Forms(?)是否可行
背景
我有一个基于组件的系统,其中控制器动态加载程序集并实例化并运行使用单个方法DoStuff()
实现公共IComponent
接口的类。
通过xml配置文件和添加包含不同IComponent
实现的新程序集来配置加载的组件。 组件为主应用程序提供实用程序功能。 虽然主程序正在做这件事,例如控制核电站,组件可能正在执行公用事业任务(在他们自己的线程中),例如清理数据库,发送电子邮件,在打印机上打印有趣的笑话,你有什么。 我想要的是使这些组件中的一个能够显示GUI,例如具有所述电子邮件发送组件的状态信息。
整个系统的生命周期如下所示
- 申请开始。
- 检查要加载的组件的配置文件。 加载它们。
- 对于每个组件,运行
DoStuff()
来初始化它,并使它在自己的线程中实现自己的生命。 - 继续做主要应用 - 工作之王,永远。
如果组件在DoStuff()
激活GUI,我还无法成功执行第3点。 它只是暂停,直到GUI关闭。 直到GUI关闭,程序才会进入第4点。
如果允许这些组件启动它们自己的Windows窗体GUI,那就太好了。
问题
当组件尝试在DoStuff()
启动GUI时DoStuff()
确切的代码行是组件运行Application.Run(theForm)
),组件因此我们的系统在Application.Run()
行“挂起”直到GUI已关闭。 好吧,正如预期的那样,刚启动的GUI工作正常。
组件示例。 一个与GUI没有任何关系,而第二个则是一个可爱的窗户,里面有粉红色蓬松的兔子。
public class MyComponent1: IComponent
{
public string DoStuff(...) { // write something to the database }
}
public class MyComponent2: IComponent
{
public void DoStuff()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
// I want the thread to immediately return after the GUI
// is fired up, so that my main thread can continue to work.
}
}
我试过这个没有运气。 即使我尝试在其自己的线程中启动GUI,执行也会暂停,直到GUI关闭为止。
public void DoStuff()
{
new Thread(ThreadedInitialize).Start()
}
private void ThreadedInitialize()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
}
是否可以分离GUI并在Application.Run()
之后返回?