簡體   English   中英

有沒有辦法讓線程安全退出而不執行thread.Abort?

[英]Is there a way to allow thread to safely exit without doing thread.Abort?

如何讓當前線程安全退出並對線程的某些資源執行刪除操作?

我使用了Thread.Abort()但使用它似乎不會釋放資源。 我正在尋找一種允許線程安全退出的方法,一旦它退出,我想執行刪除操作。

我正在使用 C# 編寫它,如果有人有任何示例或建議,請提供。

var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;                   
var task = Task.Run(() => dssPut_Command("Compile " + SystemID + "abc.dss"), tokenSource2.Token);

if (!task.Wait(TimeSpan.FromSeconds(2)))
{
    ct.ThrowIfCancellationRequested();

    bool moreToDo = true;
    while (moreToDo)
    {
        // Poll on this property if you have to do
        // other cleanup before throwing.
        if (ct.IsCancellationRequested)
        {
            // Clean up here, then...
            ct.ThrowIfCancellationRequested();
        }
        tokenSource2.Cancel();
    }               
}

go 關於此問題的最佳方法取決於您的方案,但我首選的方法之一通常是使用CancellationToken來表示線程應該正常退出。

這避免了使用Thread.Abort()這通常不是一個好主意),並且它允許您的工作人員決定何時適合取消並且它可以執行任何必要的清理。

在您發布的代碼中,調用 Task.Run() 的方法應該只創建 CancellationTokenSource,將 CancellationToken 傳遞給dssPut_Command方法,並設置cts.CancelAfter()以設置超時。 然后,只有方法dssPut_Command中的代碼應該檢查是否請求取消。

static void Main()
{
    using (var cts = new CancellationTokenSource())
    {
        // Start the worker thread and pass the
        // CancellationToken to it
        Console.WriteLine("MAIN: Starting worker thread");
        var worker = Task.Run(() => dssPut_Command(cts.Token));

        // Make the token cancel automatically after 3 seconds
        cts.CancelAfter(3000);

        // Wait for worker thread to exit
        Console.WriteLine("MAIN: Waiting for the worker to exit");
        worker.Wait();
        Console.WriteLine("MAIN: Main thread exiting after worker exited");
    }
}

static void dssPut_Command(object tokenObj)
{
    Console.WriteLine("WORKER: Worker thread started");
    var cancellationToken = (CancellationToken)tokenObj;

    // You can check if cancellation has been requested
    if (cancellationToken.IsCancellationRequested)
    {
        // If there's no need to clean up, you can just return
        return;
    }

    try
    {
        // Or you can throw an OperationCanceledException automatically
        cancellationToken.ThrowIfCancellationRequested();

        // Pass the CancellationToken to any methods you call
        // so they can throw OperationCanceledException when
        // the token is canceled.
        DoWork(cancellationToken);
    }
    catch (OperationCanceledException)
    {
        // Do any clean-up work, if necessary
        Console.WriteLine("WORKER: Worker exiting gracefully");
    }
}

static void DoWork(CancellationToken cancellationToken)
{
    // Simulating a long running operation
    Task.Delay(TimeSpan.FromMinutes(1), cancellationToken).GetAwaiter().GetResult();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM