C# 不论用何种方式退出程序,程序都会对数据库进行修改

现在有个程序,当用户登陆后,程序自动对数据库的某个字段进行了修改,修改为“已登录”。但是在退出程序时问题来了:我在窗体的FormClosed事件里,写下当窗体关闭后把数据... 现在有个程序,当用户登陆后,程序自动对数据库的某个字段进行了修改,修改为“已登录”。
但是在退出程序时问题来了:
我在窗体的FormClosed事件里,写下当窗体关闭后把数据库的“已登录”值改成“已下线”的代码。这样当我正常使用这个程序时不会出什么问题。
但是当我以非正常手段关闭程序时,比如用Ctrl+Alt+Del强制关闭程序时,程序在退出后并没有对数据库进行修改,用户的状态还是“已登录”,FormClosed事件失效。谁知道有没有什么范围更广一点的事件,让我无论如何让用什么方法退出,都会把“已登录”改成“已下线”。
在线等...
1楼,2楼均已试过。不行。
好像用了Ctrl+Alt+Del的结束进程,程序连Application.Eixt()都不需要执行就可以结束程序
1楼,我只试了FormClosing.但你说的类里些析构函数,哦不知道什么意思,我还没学到那。能大概说说怎么用么
展开
 我来答
虎用95
2010-02-21 · TA获得超过431个赞
知道小有建树答主
回答量:182
采纳率:0%
帮助的人:93.7万
展开全部
楼主是初学者。。。本来想bs你的。。。

你没看到是“FORM”Closing吗?

程序本身是app。而form只是显示在桌面上的那部分。没吃过猪肉应该看过猪跑吧:很多后台程序是没有窗体的;或者有些程序即使桌面上没有窗口了,任务管理器里面还有运行吧。。。

2楼的方法适用于关闭,如果你看看windows的消息机制就知道了,application.exit是属于一个信号(具体几号我记不住,现用现google),而任务管理器里面强制结束进程是kill掉它(另一种完全不同的信号)。当然如果你的程序懂得“自毁”(出bug被windows中止了),那又是另一回事了。

因此,如果有人懂得强制结束(无论是用任务管理期结束进程,还是用“kill”命令(cmd里面有这个命令,also没记过名字毕竟windows的任务管理器还是足够强大的),亦或是用其他软件强制结束————其实都是发送的kill信号。这时候不涉及application.exit的

结论:2楼其实是正确的,但你说的那个情况不属于application.exit而已。

My解决方案:
1. 双进程互相守护或者监视彼此,当其中任何一个被中止时候(无论是否正常中止)另一个都告诉数据库“下线”并退出自己————但这个似乎很高端,楼主写估计有难度,况且写出来很有可能会演变成吞掉所有cpu资源的杯具。

2. 其实个人觉得,你的数据库设计的不合理:如果断电呢?如果系统bluescreen呢?如果网络突然断了呢?。。。。

---------------------华丽的分割线------------------------

因此建议你在那个数据库表里面加2个栏:lastLogin和sessionId(如果你的程序不是网络程序,那就不需要sessionId了。当然网络程序也不一定要sessionId这一栏,但涉及到多用户之间互相查询时候还是有这个方便点)。
1. 每次程序启动(或者网络session建立,一个原理),设置一个值lastAccess(单机在内存,网络在session)。
2. 数据库这边,在登陆时候不仅更改“已登录”,同时更改“lastLogin”为当前时间和当前sessionId(不是网络程序忽略sessionId)。
3. 每次用户有操作,则更改lastAccess为新的当前时间。
4. 当用户正常退出时候,只需要更改为“已下线”即可。
5. 当用户非正常退出时,新加入的内容就有用啦:

---------------------华丽的分割线------------------------

如何判断到底在不在线呢?
1. 如果是“已下线”那么一定是没登陆。
2. 如果“在线”但数据库中的sessionId不存在(或者单机程序第一次启动),一定没登陆。
3. 如果“在线”+“sessionId”存在,但lastAccess(单机在内存,网络在session)超过了阀值(例如5分钟),则没登陆或者对方死机了,程序挂了etc。。。(也就是没登陆)
4. 否则必然在线

---------------------华丽的分割线------------------------

为什么不把lastAccess放在数据库里?
。。。。你要问这个问题就必须bs你了。lastAccess经常需要更新,你的数据库一定很闲或者你是想测承载能力做负载平衡吗?

---------------------华丽的分割线------------------------

注意:
1.涉及到其他用户查询状态的时候要记得这些匹配规则。
2a.【如果是网络程序】,在对方请求到达的时候也应该先比对这些条件,当然session第一次建立时候必然没登陆(假设不涉及cookie)
2b.【如果是单机程序】,那么程序第一次启动时候无所谓sessionId,肯定没登陆啦。

---------------------华丽的分割线------------------------

这么辛苦,可否多追加给几分?
FreeBS喵
2010-02-20 · TA获得超过161个赞
知道小有建树答主
回答量:213
采纳率:100%
帮助的人:80.9万
展开全部
Closing你试过吗?
因为C#的窗体推出事件封装的是WINDOWS标准库的WM_DESTROY消息,但是不能从底层WM_DESTROY来处理,只能看.NET FW有没有提供相应的事件了,我觉得你应该试试Closing这个事件,在不行的话再在窗体的类里写个析构函数,把操作放在析构函数里
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
justkeepmoving
2010-02-20 · TA获得超过486个赞
知道小有建树答主
回答量:462
采纳率:0%
帮助的人:553万
展开全部
我知道哈!楼主,你把你的处理代码写在program.cs里的application.run()下面就可以了哈!保证得行!
祝你成功!不行的话hi我哈!!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
pppop3
2010-02-21 · TA获得超过316个赞
知道小有建树答主
回答量:488
采纳率:0%
帮助的人:389万
展开全部
在你主窗体的析构函数中写
Dispose() 这个函数中写你的东西 这个函数在窗体的designer.cs文件里 或者跟楼上说的在主程序集的program的main()函数中写也可以
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
rostazheng
2010-02-21 · 超过15用户采纳过TA的回答
知道答主
回答量:92
采纳率:0%
帮助的人:49.9万
展开全部
就取快捷键的事件做处理,当快捷键Ctrl+Alt+Del的时候,就触发一个事件,把数据库进行修改……
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式