[英]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.