C#:内部工作:事件,Control.BeginInvoke和程序退出=中断?

时间:2012-03-15 18:39:25

标签: c# events exit begininvoke

我正在创建一个包含多个项目的程序,并且一些项目会向主项目消息报告以进行日志记录。

由于我使用的是Asynch套接字,其中一些消息会在不同的线程中返回,所以一旦它们到达主线程,我会检查InvokeRequired,如果是,我使用this.BeginInvoke来处理日志记录。

我需要在UI线程中处理它,特别是在服务器的情况下,我在ListBox上显示最后记录的消息,这样我就可以在测试期间跟踪操作的进度。

我知道有时可能会发生一些消息被切换,但是现在我可以接受它。出于某种原因,如果我使用Invoke而不是BeginInvoke,如果我在客户端连接时停止它,服务器将崩溃,甚至不会给出任何异常。但是使用BeginInvoke我克服了这一点。

我的问题是在程序终止的情况下了解事件和BeginInvoke如何工作。如果一个事件在队列中或者在程序关闭之前调用了BeginInvoke,它会终止imediatly,取消所有内容吗?或者它会执行所有挂起的操作,在我的情况下记录待处理的消息,然后退出?

2 个答案:

答案 0 :(得分:2)

如果要确保执行所有BeginInvoked委托,则必须延迟关闭表单。您可以通过将其分为两个步骤,将另一个BeginInvoke委托附加到实际关闭表单的队列来完成此操作。像这样:

    private bool closing;

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (!closing) {
            closing = true;
            // Do your stuff
            //...
            this.BeginInvoke(new Action(() => this.Close()));
            e.Cancel = true;
        }
        base.OnFormClosing(e);
    }

答案 1 :(得分:0)

当您调用BeginInvoke更新UI时,代码将由线程池中的线程执行。如果代码引发异常,它将只终止线程,而不是整个应用程序。这就是为什么你看到你的程序没有崩溃的原因。

刚刚调用BeginInvoke时,程序立即终止。其余的操作(日志记录)将不会被执行,因为来自线程池的线程