![](/img/trans.png)
[英]How to stop a service when a thread is doing work (without using 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.