加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 确保线程终止时“finally”在同一线程上运行

发布时间:2020-12-15 21:37:30 所属栏目:百科 来源:网络整理
导读:这对你们来说是一个难题.我有一个多线程程序,其中一些线程使用托管资源,如锁和信号量.某些锁定释放原语只能从完成锁定获取的同一线程执行. 所以这是我的谜题:我包装了这些类型的操作:try {lock-acquire … do something} finally {lock-release},但有时当
这对你们来说是一个难题.我有一个多线程程序,其中一些线程使用托管资源,如锁和信号量.某些锁定释放原语只能从完成锁定获取的同一线程执行.

所以这是我的谜题:我包装了这些类型的操作:try {lock-acquire … do something} finally {lock-release},但有时当我的线程终止时,finally子句由.NET垃圾收集线程执行,不是我的话. (具体情况实际上涉及在“使用”语句中分配对象的处理;有关详细信息,请参见下文)

演示这有点棘手;我在Isis2中一直看到它,我发现通过检查acquire和finalize块中的thread-id会发生这种情况.但我没有为您提供3线演示,对此我很抱歉.我知道这会更容易提供帮助.

有没有办法可以延迟线程终止,直到与该线程关联的所有挂起的finalize块都执行完毕?

—-为Mark添加的详细信息—-

我真正做的是涉及一个相当精细的自我调整锁定包,它具有各种锁定抽象(有界缓冲区,障碍,正常锁等),具有线程优先级,旨在自我检测死锁,优先级反转,非常慢的锁定授权和其他问题.我的代码足够复杂并且有足够的线程,所以我需要这个来调试它.

我的基本构造风格的一个例子是:

LockObject  myLock = new LockObject("AnIsis2Lock");

...

using(new LockAndElevate(myLock)) { stuff }

一个LockObject是一个自我监控的锁…一个LockAndElevate记下我锁定它(在这种情况下),然后在我解锁时跟踪处理.所以我正在利用这样一个事实,即当块完成时使用应该处理新对象 – 即使它抛出异常.

我所看到的是,线程经常终止,但实际上并没有使用dispose事件;他们在其他线程上运行得晚.这只发生在我的一个线程终止时;在正常执行中,整个事情就像一个魅力.

因此,自从使用翻译尝试…最后,我的问题是根据最终条款发布的.

解决方法

到目前为止,这是我对自己问题的最佳答案,主要基于调试Isis2行为的经验.

如果线程没有终止,“using(x = new something()){}”(映射到“try {x = new something(); …} finally {x.dispose}”)就像你一样可以预料:当退出代码块时会发生处理.

但例外会破坏控制流程.因此,如果您的线程抛出IsisException,或者某些东西在“某事”中这样做,那么控制将传递给该异常的catch.这是我正在处理的情况,我的catch处理程序在堆栈上更高. C#/ .NET面临一个选择:它首先捕获IsisException,还是首先执行dispose?在这种情况下,我相当肯定系统首先系统地执行IsisException.因此,已分配对象“x”的终结器尚未执行但可运行且需要尽快调用.

[注意:对于那些好奇的人来说,Using语句以调用Dispose结束,但根据文档,推荐的行为是使用finalizer~some(){this.Dispose;只是为了涵盖所有可能的代码路径.然后可以多次调用Dispose,并且应该保留一个标志,锁定并发性,并且只在首次调用Dispose时处理您的托管资源.

现在关键的问题是终结器显然可能在你的线程有机会终止之前运行,在这种情况下终止你的线程的被捕获的异常;如果没有,C#将通过在GC终结器线程上调用dispose来处置该对象.因此,如果在我的代码中,x.Dispose()解锁了可能发生错误的东西:锁获取/释放必须在.NET上的同一个线程中发生.这对你和我来说都是潜在的错误来源!在我的异常处理程序中调用GC.WaitForFinalizers似乎有助于这种情况.我不太清楚这是否真的保证不会发生坏事.

我自己的代码中的另一个严重错误是我错误地在几个线程中捕获了ThreadAbortException,原因是对这些工作方式的误解.不要这样做.我现在可以看到它会导致.NET出现严重问题.只是不要使用Thread.Abort.

所以在这种理解的基础上,我修改了Isis2,它现在运行得很好;当我的线程终止时终结器确实看起来运行正常,在线程退出之前似乎发生了dispose(因此在它的id被重用之前,这导致了我的混乱),并且一切都对世界有益.那些使用线程,优先级和自我管理的锁/障碍/有界缓冲区和信号量的人应该谨慎:潜伏在这里的龙!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读