首页 新闻 会员 周边

C#中为什么调用 System.Environment.Exit(0);会偶尔报错System.ComponentModel.Win32Exception--创建窗口句柄时出错

0
[已解决问题] 解决于 2020-04-13 08:52

未处理System.ComponentModel.Win32Exception
ErrorCode=-2147467259
HResult=-2147467259
Message=创建窗口句柄时出错。
NativeErrorCode=1406
Source=System.Windows.Forms
StackTrace:
在 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
在 System.Windows.Forms.Control.CreateHandle()
在 System.Windows.Forms.Control.get_Handle()
在 System.Windows.Forms.Control.get_Focused()
在 System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.DetermineState(Boolean up)
在 System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintThemedButtonBackground(PaintEventArgs e, Rectangle bounds, Boolean up)
在 System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintWorker(PaintEventArgs e, Boolean up, CheckState state)
在 System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintUp(PaintEventArgs e, CheckState state)
在 System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.Paint(PaintEventArgs pevent)
在 System.Windows.Forms.ButtonBase.OnPaint(PaintEventArgs pevent)
在 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
在 System.Windows.Forms.Control.WmPaint(Message& m)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
在 System.Windows.Forms.Button.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
InnerException:

😀明笔记的主页 😀明笔记 | 初学一级 | 园豆:13
提问于:2020-03-11 09:03

找不出什么原因导致,报错是偶然性的。有没有可以解释一下。有什么可能导致的?

😀明笔记 4年前

最让我不理解的是,调用Environment.exit()方法不是退出并释放所有资源嘛,怎么会报错创建串口句柄的错?退出的时候还会创建的?

😀明笔记 4年前
< >
分享
最佳答案
0

最好还是走正常流程,把所有窗口关闭,然后把主窗口关闭。这时 program 的 main 方法会走到结尾自动退出进程。你这个调用一般是给控制台用的,或者在 main方法末尾调用,给 void main 一个返回退出代码给系统的机会。WinForm程序的生命周期比控台复杂,还牵扯到各种内核资源,尽量走正常流程。
如果是wpf,可以用 application 的 shutdown 方法安全退出程序。

奖励园豆:5
coredx | 小虾三级 |园豆:678 | 2020-03-12 15:22

我是用Windows窗体不是WPF,如果是wnform有什么方法可以安全退出程序吗?

😀明笔记 | 园豆:13 (初学一级) | 2020-03-12 16:37

@😀明笔记: 建议还是尽量走正常流程。如果捕获到异常觉得应该退出,看情况,如果要做一些补救工作再退出,可以catch异常,完成处理后从窗体对象的变量上用 form 从 control 继承的 invoke 方法向 form 发送窗体关闭事件,相当于用代码点叉,或者调用 form 的 close 方法,也是主动触发窗体关闭事件,invoke 的好处是在多线程调用UI控件不会报错,如果没开多线程两种方法都一个效果。如果窗体不是主窗体,可以主窗体注册子窗体的关闭事件,在事件处理中继续向自己发送关闭事件,链式关闭窗体。当主窗体关闭后程序就自己退出了。
如果不管异常,可以注册app 的未处理异常事件,任何未处理异常到最后会触发这个事件,处理完事件后 .net 框架会自动强制退出。可以在这个事件中做后处理。
基本思路就是在你想退出程序的地方用代码模拟点叉,触发窗体的正常关闭流程。主窗体关闭后程序就自动退出了。或者等着异常导致 .net 强制结束进程。

coredx | 园豆:678 (小虾三级) | 2020-03-12 17:14

@coredx: 不用模拟点叉啊,我本来就是自己手动点叉,然后在窗体closing事件中添加Environment.Exit(0)代码然后报错的。

😀明笔记 | 园豆:13 (初学一级) | 2020-03-12 17:22

@😀明笔记: 既然如此就不用管就好了。closing 事件只是告诉外界我要关了,有什么后事要处理的赶快,事件处理结束窗体会自动关闭,除非设置关闭事件参数的取消关闭属性为 true。如果关闭的是主窗体,程序自己就退出了,不用管的。如果不是主窗体,你就在子窗体打开的时候让主窗体去注册子窗体的 closing 事件,主窗体的处理方法被触发后再调用自己的 close 把主窗体自己关掉。就像链条一样,a窗口注册b窗口的关闭事件,b又注册c的,c关闭会触发b,b把自己关掉,b又会触发a,a再把自己关掉。全关完了程序自己就退了。

coredx | 园豆:678 (小虾三级) | 2020-03-12 17:36

@😀明笔记: 这个应该注册 closed 事件。因为 closing 是可能取消关闭的。closed 才能保证窗口一定是关闭了。

coredx | 园豆:678 (小虾三级) | 2020-03-12 17:39

@coredx: 问题是。我只有一个窗体哦。然后调用了Environment.Exit(0)就偶然性的报错。

😀明笔记 | 园豆:13 (初学一级) | 2020-03-12 17:42

@😀明笔记: 具体原因我也不清楚,我只是在 WPF 里用过,偶尔会出现窗口关闭了,进程还在后台运行,也不报错,什么反应都没有,跟鬼子进村似的。
你这个错误一看就和内核对象有关,调试 C# 也没用,.net 也只是把系统错误报给你。要研究清楚问题出在哪里得深入 windows 内核原理。我只能说 WinForm 的对象生命周期很复杂,还牵扯 .net 框架无权管理的系统内核资源。我们能做的就是按照 Windows 的规矩办事,不要老想搞事,出问题系统可不管,毕竟是你先坏了规矩。想在 Windows 的地盘混就得守人家的规矩。毕竟 Windows 是商业闭源软件,如果涉及技术机密,人家也不会告诉你为什么。如果不是大神建议不要纠结,这不是普通码农能搞定的问题。按规矩办事就行。

coredx | 园豆:678 (小虾三级) | 2020-03-12 18:33

@coredx: 哈哈哈哈,你的话深入我心

😀明笔记 | 园豆:13 (初学一级) | 2020-03-12 22:40
其他回答(3)
0
RosonJ | 园豆:4910 (老鸟四级) | 2020-03-11 11:27

Application.Exit() 会导致有些线程退出不干净?不是吗?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-03-11 11:30

@😀明笔记:
看一些文章確實會有這個問題,只能說是建議

支持(0) 反对(0) RosonJ | 园豆:4910 (老鸟四级) | 2020-03-11 16:14

@RosonJ: 目前主窗体要运行一个包含委托方法的线程,线程里面有一个循环函数,如果采用Application.Exit()会报错无法访问已释放的资源。采用Environment.Exit(0)就没有问题。。你有其他好的办法嘛?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-03-11 16:17
0

总结:问题找不到解决方案,但是从热心网友们得到了预防的经验。软件正常运转,正常停止,尽量少依赖强制性的函数。

😀明笔记 | 园豆:13 (初学一级) | 2020-04-13 08:51
0

遇到了同样的问题,自己解决了,解决方法是每一个资源回收Dispose()方法后面加一个10ms的sleep()...

Uioo | 园豆:202 (菜鸟二级) | 2021-09-03 16:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册