簡體   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