【发布时间】:2010-07-18 08:46:52
【问题描述】:
我在显示启动表单的方式上遇到了一个奇怪的问题,导致InvalidAsynchronousStateException 被抛出。
首先,这是我启动启动表单的 Main{} 代码:
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Thread splash = new Thread(new ThreadStart(ShowSplash));
splash.Start();
Application.Run(new MainForm());
}
static void ShowSplash()
{
using (SplashForm splash = new SplashForm())
{
Application.Run(splash);
}
}
我正在使用 .NET2.0 和 Win XP。
在一些应用程序运行了 5 个小时的测试期间,我注意到异常的数量偶尔会增加一到两个。 (PerfMon 获得的数字,查看 '# of Exceps Throw' 计数器。)这些异常似乎被运行时捕获和吞噬,因为它们确实 不会激起涟漪并导致应用程序本身出现任何问题。至少我无法确定。
我发现当系统触发 UserPreferenceChanged 事件时会引发异常。既然发现了这一点,我就可以生成异常 随意改变背景图片或屏保等
我自己并没有在代码的任何地方明确订阅此事件,但我了解(通过 Google 的力量)所有顶级控件和表单都订阅 自动到这个事件。
我还没有确定为什么这个事件首先被触发,因为它似乎发生在应用程序运行过夜时,但我想这是另一个有待解决的谜。
现在,如果我停止运行启动表单线程,异常就会消失。运行线程,它回来了。那么,似乎没有取消订阅该事件,这可能导致后续异常?
有趣的是,如果我用默认的开箱即用表单替换我的初始表单,问题仍然存在:
static void ShowSplash()
{
using (Form splash = new Form())
{
Application.Run(splash);
}
}
在显示此表单时,任何 UserPreferenceChanged 事件都不会导致任何异常。一旦表单关闭,线程退出,就会抛出异常。
进一步的研究将我带到this Microsoft article,其中包含以下评论:
常见的原因是闪屏 在辅助 UI 线程上创建或 在工作人员上创建的任何控件 线程。
嗯,从外观上看是有罪的。请注意,我的应用并没有冻结或做任何不愉快的事情。
目前,这更像是一种好奇心,但我担心将来这里可能会有一些隐藏的讨厌鬼等着咬。
在我看来,Application.Run 启动的表单或消息泵在终止时没有正确清理。
有什么想法吗?
【问题讨论】:
-
有趣;如果你使用
ShowDialog作为splash,错误还会出现吗? -
@Marc:是的。在 Debug 和 Release 版本上也试过这个。你能重现它吗?
-
很遗憾,我目前还不能尝试。
标签: c# winforms exception splash-screen