繁体   English   中英

如何正确使用Thread.Abort()?

[英]How to use Thread.Abort() properly?

线程中止时会导致什么问题?

我需要在代码中使用Thread.Abort() ,因为线程运行的复杂代码中包含很多循环,对象和条件。

我知道Thread.Abort()在使用Monitor时可能导致死锁,也可以防止资源被释放,但是我可以处理这些问题。

我使用IDisposable / using模式或捕获ThreadAbortException来保证释放所有资源并停止异步操作。

该应用程序现在似乎可以正常工作。 但是,由于代码非常复杂,因此我不确定在中止线程时是否可能会出现罕见的情况,从而导致内存泄漏或未处理的异常。

如果线程执行代码时中止线程,是否有任何.net类(例如FileStreamDictionary )会导致问题? 还是我应该注意的其他一些问题?

Thread.Abort的问题在于,您的ThreadAbortException可以(几乎)在任何两个指令之间引发。

如果您采用一些非常简单的代码,例如:

public void M()
{
    using (CreateThing())
    {
    }
}

public IDisposable CreateThing() => null;

并查看生成的C#和IL

public void M()
{
    IDisposable disposable = CreateThing();
    try
    {
    }
    finally
    {
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }
}

您可以看到在CreateThing和进入try块之间有一些指令。 机会很小,如果立即调用Thread.Abort ,则不会处理您的对象。

因此,使用IDisposableusing 不能保证面对Thread.Abort可以释放资源。

有很好的理由为什么要从.NET Standard中删除Thread.Abort ,以及为什么应改用CancellationToken

您应该使用CancellationToken ,并且您的代码应该检查它是否已在适当的安全点被取消(使用CancellationToken.ThrowIfCancellationRequested() )。


Monitor.Enter说一句, lock语句使用Monitor.Enter重载,它返回一个布尔值,说明是否实际获取了锁,并且:

lock (lockObject)
{
}

编译为:

bool lockTaken = false;
try
{
    Monitor.Enter(lockObject, ref lockTaken);
}
finally
{
    if (lockTaken)
        Monitor.Exit(lockObject);
}

为了避免这个问题。

但是,在使用任何其他同步方法时(仅lock ,您将不会奢侈,因此您很容易死锁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM