c# – 关闭WinForm应用程序时的一次性对象生命周期
我有一个连接到数据库的
Windows窗体应用程序.所有重型SQL查询都在后台线程中实现,因此它们不会阻塞主线程.其中一些查询需要数据库事务.使用关键字初始化所有Db对象以确保正确处理:
using (conn = OpenConnection()) { using (tran = conn.BeginTransaction()) { // Do stuff } } 现在,一些用户是住院病人,他们只是在应用程序在后台线程中有活动事务时关闭应用程序.我们的数据库管理员发现这些事务在数据库上仍然活动了几分钟甚至更长时间,这是一个问题,因为打开事务会锁定数据. 那么,当用户决定关闭应用程序时,这些线程中的线程和一次性对象会发生什么?线程是使用Task.StartNew()方法创建的. 解决方法
任务
Foreground and Background Threads:
这也适用于线程池中的线程,这些线程在启动新任务时默认使用,而不指定其他选项: Task Schedulers
Foreground and Background Threads:
关于申请终止的事实 在那之后,我还没有找到任何进一步的信息,在线程终止后发生了什么.我所做的,是简单的测试: static void Main(string[] args) { Task.Factory.StartNew(Method); Task.Delay(1000); } static void Method() { try { while (true) { } } finally { File.WriteAllText(@"C:PolygonTest.txt","test"); } } 答案是,最终块没有被执行. 解决方案 ThreadAbortException – 不在这里 像ThreadAbortException这样的.NET中有一些功能称为线程终止的答案,但是:
Process.Exited事件 – 不在这里 如果您运行其他进程,可以使用以下代码: var myProcess = new Process(); myProcess.EnableRaisingEvents = true; myProcess.Exited += new EventHandler(CleanUp); 但是,对于当前流程,这也不起作用. AppDomain.CurrentDomain.ProcessExit – 有效 但是,Avneesh建议的解决方案适用于当前流程: static void Main(string[] args) { AppDomain.CurrentDomain.ProcessExit += CleanUp; Task.Factory.StartNew(Method); Task.Delay(1000); } static void Method() { try { while (true) { } } finally { CleanUp(null,EventArgs.Empty); } } static void CleanUp(object sender,EventArgs args) { File.WriteAllText(@"C:PolygonTest.txt","test"); } 流程终止 有关rosources的问题的答案可以在Terminating a Process文章中找到:
以及如何终止进程:
数据库连接 连接是一种资源,因此如果处理终止,则释放其所有资源.我检查了它在实践中的样子. C#代码: SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=[database_name];Integrated Security=True"); connection.Open(); Debugger.Launch(); connection.Close(); connection.Dispose(); 会话查找的T-SQL查询: SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE nt_user_name = '[user_name]' AND program_name = '.Net SqlClient Data Provider' 我注意到,对于每个新连接,都创建了新会话.最有趣的是,在明确关闭或处理连接后,该会话未被释放.但是 – 目前我们感兴趣的领域 – 会话在申请流程终止时被释放. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |