我正在写一个IRC机器人/客户端,我偶然发现了一个小问题。每个通道都将显示在一个单独的窗口中,并带有一组自己的控件。我创建了一个合适的窗口类ChanWindow:
public partial class ChanWindow : Form
{
string Chan;
string Username;
IRCBot Caller;
public ChanWindow(string channame, string uname, IRCBot caller)
{
Caller = caller;
Caller.Join(channame);
InitializeComponent();
Chan = channame;
Name = Chan;
Username = uname;
}
//various functionalities required for window use
}
我将窗口对象存储在ConcurrentDictionary<string, ChanWindow>
中,因为(应该是)一个单独的线程将适当编辑的消息发送到窗口。它们都在循环中初始化:
foreach (string chan in Chanlist)
{
Chans[chan] = new ChanWindow(chan, Name, this);
Chans[chan].Show();
}
其中Chanlist
是要加入的List<string>
个频道。
目睹了程序启动后不久窗口死亡,我在ChanWindow构造函数的行Username = uname;
中放置了一个断点,发现它在窗口死亡之前就被绊倒了。
我的主要问题是:原因是什么?如何避免?使用词典是个好主意吗?我应该构建一些能够处理窗口功能的包装器/容器类吗?
答案 0 :(得分:4)
我怀疑你没有
Application.Run(new ChanWindow());
在您的主要入口点(默认为Program.Main()
)。
如果你没有使主窗口线程Show
成为表单,并等待它关闭,那么任何东西都不会阻止线程完成并且你的应用程序关闭。
如果你想独立启动消息循环,你仍然需要调用Application.Run()
,这样主线程就会开始处理事件。如果在没有参数的情况下调用它,则消息循环不会自动停止,因此当您希望消息循环停止时,您必须显式调用Application.Exit()
。然后主线程将继续到程序结束并结束。
您可以对代码执行此操作,
foreach (string chan in Chanlist)
{
Chans[chan] = new ChanWindow(chan, Name, this);
Chans[chan].Show();
}
Application.Run();
但是,如果你想自动退出应用程序,你可以继承自己的ApplicationContext
,如already linked MSDN documentation中所述,并将其传递给Application.Run()
,这就是它之后的用途所有