我有這樣的代碼如何停止一個線程在其他結束
Thread thread1 = new Thread(this.DoSomething1);
Thread thread2 = new Thread(this.DoSomething2);
thread1.Start();
thread2.Start();
我需要完成立刻殺死對方的第一個線程。 請注意,該線程不是那種運行一段時間的樣子,所以我不能使用一個靜態變量來告訴線程停止。哪個線程會先結束?
我有這樣的代碼如何停止一個線程在其他結束
Thread thread1 = new Thread(this.DoSomething1);
Thread thread2 = new Thread(this.DoSomething2);
thread1.Start();
thread2.Start();
我需要完成立刻殺死對方的第一個線程。 請注意,該線程不是那種運行一段時間的樣子,所以我不能使用一個靜態變量來告訴線程停止。哪個線程會先結束?
你在這些線程中做什麼非常重要。如果在兩者中都有for循環,則可以通過讀取循環開始或循環體中任何位置的共享變量來停止線程。如果它只是沉重的計算(複雜的業務流程或複雜的數學事物),那麼在某件事情中殺死一個線程甚至是危險的。
殺死一個線程是_always_危險的。它應該始終通過響應同步原語而協作退出。 – xxbbcc
理想情況下,您希望使用取消令牌或靜態變量來安全地取消線程。
如果你決定使用的CancellationToken/tokenSource:
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
...
static void DoSomething1or2(CancellationToken token, CancellationTokenSource tokenSource)
{
//Do other work here
//Since you said neither of your tasks were looping, just put this where
//you'd want to cancel the thread
if(token.IsCancellationRequested)
return; // or token.ThrowIfCancellationRequested();
//do some more stuff here
tokenSource.IsCancellationRequested = true;
}
如果您DoSomething的方法循環,那麼你可以在開始或每次循環結束時檢查一個布爾值,看看是否另一個線程完成。這種技術與cancellationToken非常相似。
if(otherThreadIsActive && originalCondition)
{
//do stuff here
}
如果你不能等待迭代完成,否則無法使用取消標記,那麼我建議你閱讀this thread on aborting。最好不要使用它,除非它是絕對必要的。
最好的辦法:使用取消標記/ tokenSource
下一個最好的方法:使用某種布爾來決定何時終止
Thread
是「射後不理」你開始並且再也不會互動的任務。如果您需要與線程交互,例如在線程啓動後停止線程,或者需要知道線程何時完成,則應使用Task.Run
而不是Thread
。如果您想在任務仍在運行時取消任務,則需要CancellationTokenSource
。
var cts = new [] {
new CancellationTokenSource(),
new CancellationTokenSource()};
var ts = new[]
{
Task.Run(() => DoSomething1(cts[0].Token), cts[0].Token),
Task.Run(() => DoSomething2(cts[1].Token), cts[1].Token)
};
var w = Task.WaitAny(ts);
for (int i = 0; i < cts.Length; i++)
{
if (i != w) cts[i].Cancel();
}
你DoSomething
旨意必須監控CancellationToken.IsCancellationRequested
取消並執行清理。您需要將令牌傳遞給Task.Run
以檢測線程是否引發異常,但我沒有說明。欲瞭解更多信息,請諮詢How to Cancel a Task and Its Children。
我在過去處理同步線程取消時所做的工作是在類中有一個靜態事件來激活線程。這些線程執行所有監聽這個靜態事件的不同類的函數。當這個事件觸發時,volatile private bool _aboutRequested
被設置爲真,這是在啓動線程執行類中找到的。在線程執行循環中,最後一件事是檢查此退出請求的布爾值,如果爲true,則優雅地退出。
有沒有安全的方法殺死一個線程。至於等待其中一個任務完成,只需使用'Task.Run'而不是創建手動線程,並且可以使用'Task.WhenAny'。 – Luaan
這聽起來有點[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。你的線索究竟在做什麼,你需要他們以這種方式行事? –
夥計們,感謝您的快速響應,但: 1.我的線程不會循環。 2.他們完成不同的工作。 – user3671974