2

我目前正在编写一个 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
}

我将窗口对象存储在 a 中ConcurrentDictionary<string, ChanWindow>,因为(应该有)一个单独的线程将适当编辑的消息发送到窗口。它们都在循环中初始化:

 foreach (string chan in Chanlist)
 {
     Chans[chan] = new ChanWindow(chan, Name, this);
     Chans[chan].Show();
 }

加入的频道Chanlist在哪里。List<string>目睹了程序启动后不久窗口就死了,我在Username = uname;ChanWindow 构造函数的行中放置了一个断点,并注意到它在窗口死前立即被触发。

我的主要问题是:原因是什么,我该如何避免?使用字典是个好主意吗?我应该构建某种可以处理窗口功能的包装器/容器类吗?

4

1 回答 1

4

我怀疑你没有

Application.Run(new ChanWindow());

在您的主要入口点(Program.Main()默认情况下)。

如果您不将主 GUI 线程Show设置为表单,并等待它关闭,则不会阻止线程完成和您的应用程序关闭。


如果您想独立启动消息循环,您仍然需要调用Application.Run()以便主线程开始处理事件。如果您在没有参数的情况下调用它,则消息循环不会自动停止,因此Application.Exit()当您希望消息循环停止时,您必须显式调用。然后主线程将继续到程序的末尾并结束。

您可以对您的代码执行此操作,

 foreach (string chan in Chanlist)
 {
     Chans[chan] = new ChanWindow(chan, Name, this);
     Chans[chan].Show();
 }

 Application.Run();

但是,如果您想自动退出应用程序,您可以继承您自己的应用程序ApplicationContext,如已链接的 MSDN 文档中所述,并将其传递给Application.Run(),毕竟这就是它的用途。

于 2013-04-26T14:59:46.790 回答