在 .NET 中中止线程时,这段代码会损坏吗?

Posted

技术标签:

【中文标题】在 .NET 中中止线程时,这段代码会损坏吗?【英文标题】:In .NET when Aborting Thread, can this piece of code get corrupted? 【发布时间】:2010-04-15 14:35:01 【问题描述】:

简介:

在复杂的多线程应用程序(企业服务总线 ESB)中,我需要使用 Thread.Abort,因为该 ESB 接受用户编写的与硬件安全模块通信的模块。因此,如果此模块死锁或硬件停止响应 - 我只需卸载此模块,此服务器应用程序的其余部分必须继续运行。

所以有中止同步机制确保代码只能在用户部分中止,并且该部分必须标记为 AbortAble。如果发生这种情况(中止),则有可能在这段代码中抛出 ThreadAbortException:


public void StopAbortSection()
        
            var id = Thread.CurrentThread.ManagedThreadId;
            lock (threadIdMap[id])
            
                ....
            
        

例如模块在AbortSection(通过调用类似方法StartAbortSection进入),ServerAplication决定中止用户模块,但在此决定之后,实际Thread.Abort之前,模块通过调用该方法进入NonAbortableSection,但实际上是锁定那个锁定对象。

所以 lock 会阻塞直到 Abort 被执行,但是 abort 也可以在到达这个代码块之前被执行。但是使用这种方法的对象是必不可少的,我需要确保这段代码在任何时候都可以安全中止(不会被破坏 - 例如,我不知道从字典中读取时会发生什么......)。

不得不提一下threadIdMap是Dictionary(int,ManualResetEvent),而锁定对象是ManualResetEvent的实例。

我希望你现在能理解我的问题。对不起它的大。

【问题讨论】:

Thread.Abort 不是您的线程问题可接受的解决方案。 我知道 Thread.Abort 的错误,但这是必要的 :(. 【参考方案1】:

异常被“违反”是什么意思?

ThreadAbortException 可以在代码中的任何位置抛出。锁根本不会影响这一点,除非是一个线程正在中止另一个线程,中止线程的代码在锁内,并且线程锁定在同一个对象上。

线程必须锁定同一个对象才能生效。除非字典中有不同的项目包含对相同 ManualResetEvent 对象的引用,否则锁是完全没用的。

【讨论】:

现在我看到一个以错误方式定义的问题..,抱歉,请重新编辑。

以上是关于在 .NET 中中止线程时,这段代码会损坏吗?的主要内容,如果未能解决你的问题,请参考以下文章

.NET 中的线程中止

可以像中止一个Thread(Thread.Abort方法)一样中止一个Task吗?

.Net 异步委托中止

上传文件处理数据的时候提示 正在中止线程

线程在完成执行代码之前在动态库中中止

std::thread,在线程中抛出异常会导致 Visual C++ 中的中止错误