[英]How to use Thread.Abort() properly?
线程中止时会导致什么问题?
我需要在代码中使用Thread.Abort()
,因为线程运行的复杂代码中包含很多循环,对象和条件。
我知道Thread.Abort()
在使用Monitor
时可能导致死锁,也可以防止资源被释放,但是我可以处理这些问题。
我使用IDisposable
/ using
模式或捕获ThreadAbortException
来保证释放所有资源并停止异步操作。
该应用程序现在似乎可以正常工作。 但是,由于代码非常复杂,因此我不确定在中止线程时是否可能会出现罕见的情况,从而导致内存泄漏或未处理的异常。
如果线程执行代码时中止线程,是否有任何.net类(例如FileStream
, Dictionary
)会导致问题? 还是我应该注意的其他一些问题?
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
,则不会处理您的对象。
因此,使用IDisposable
和using
不能保证面对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.