任务管理器中的“结束任务"始终设置 CloseReason.UserClosing [英] 'End Task' in Task Manager always sets CloseReason.UserClosing

查看:78
本文介绍了任务管理器中的“结束任务"始终设置 CloseReason.UserClosing的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果客户试图强制关闭应用程序,我想记录.我知道没有机会捕获进程终止.但是应该可以通过主窗体关闭事件获知'CloseReason.TaskManagerClosing' 的原因.

I want to log if a customer tries to force close the application. I'm aware of having no chance to catch a process kill. But it should be possible through the main form closing event to get informed about the 'CloseReason.TaskManagerClosing' reason.

但是我在 Windows 8.1 下所做的任何测试我总是得到 CloseReason.UserClosing 原因.但在这种情况下(与法线 CloseReason.UserClosing 相比)我有大约 0.2 秒的时间在我的程序被杀死后运行用户代码!

But any tests I did under Windows 8.1 I always got a CloseReason.UserClosing reason. But in this case (compared to a normals CloseReason.UserClosing) I've about 0.2s to run user code afterwards my program is killed!

这是 Windows 8.1 中的新行为吗?

Is this a new behavior in Windows 8.1?

推荐答案

是的,我看到了.是的,这是 Windows 更改,以前版本的任务管理器直接向窗口发送 WM_CLOSE 通知.我现在看到它发出与使用关闭按钮(WM_SYSCOMMAND、SC_CLOSE)关闭窗口时发出的完全相同的命令.或者按 Alt+F4 或使用系统菜单.所以 Winforms 不能再区分任务管理器和用户关闭窗口之间的区别,你确实得到了 CloseReason.UserClosing.

Yes, I see this. And yes, this is a Windows change, previous versions of Task Manager sent the window the WM_CLOSE notification directly. I now see it issue the exact same command that's issued when you close the window with the Close button (WM_SYSCOMMAND, SC_CLOSE). Or press Alt+F4 or use the system menu. So Winforms can no longer tell the difference between the Task Manager and the user closing the window and you do get CloseReason.UserClosing.

接下来会发生什么是预料之中的,如果您没有足够快地响应关闭命令,那么任务管理器会立即使用 TerminateProcess() 暗杀您的程序.

What happens next is expected, if you don't respond to the close command quickly enough then Task Manager summarily assassinates your program with TerminateProcess().

请记住,当用户通过任务管理器中止程序时尝试保存数据是一种不好的做法.如果您的程序出现故障,您的用户通常会使用它,您不能再信任数据并且您冒着写垃圾的风险.现在,您的保存代码被中止、部分写入的文件或数据库数据不再可用的可能性很高,这使情况更加复杂.

Do keep in mind that trying to save data when the user aborts your program through Task Manager is a bad practice. Your user will normally use this if your program is malfunctioning, you can't really trust the data anymore and you risk writing garbage. This is now compounded by your saving code being aborted, high odds for a partially written file or dbase data that isn't usable anymore.

对此没有简单的解决方法,修补 Windows 以恢复旧行为的可能性非常接近于零.以事务方式保存数据非常重要,这样在保存代码中止时就不会破坏有价值的数据.对文件数据使用 File.Replace(),对 dbase 写入使用 dbase 事务.

There is no simple workaround for this, the odds that Windows is going to be patched to restore old behavior are very close to zero. It is very important that you save your data in a transactional way so you don't destroy valuable data if the saving code is aborted. Use File.Replace() for file data, use a dbase transaction for dbase writes.

检测这种情况的一种不完美的方法是使用 Form.Deactivate 和 Activate 事件.如果您看到了 Deactivate 事件并且 FormClosing 事件被触发,那么另一个程序正在终止您的程序的可能性是合理的.

An imperfect way to detect this condition is by using the Form.Deactivate and Activate events. If you saw the Deactivate event and the FormClosing event fires then reasonable odds that another program is terminating yours.

但是您处理这种情况的正常方式是常见的,如果用户在没有保存数据的情况下结束程序,那么您会显示一个对话框,询问是否保存数据.任务管理器确保这不会比这更进一步.

But the normal way you deal with this is the common one, if the user ends the program without saving data then you display a dialog that asks whether to save data. Task Manager ensures that this doesn't go further than that.

这篇关于任务管理器中的“结束任务"始终设置 CloseReason.UserClosing的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆