[英]C# Pause a working thread from the main thread
所以,我想從主線程暫停一個工作線程,如果我決定,我希望能夠恢復它的活動。 之前,我使用了myThread.Suspend()
和Resume()
但它已被棄用,不建議再使用它。
你們中的任何人都可以給我一個替代方案嗎? 謝謝!
一種方法是使用ManualResetEvent
或AutoResetEvent
對象。 等待信號的線程將被阻塞,直到某事將在事件對象上調用 Set()。
當然,這僅適用於您控制在工作線程中執行的循環。
private ManualResetEvent runningWork = new ManualResetEvent(true);
public void Main()
{
//
// suspend
runningWork.Reset();
// resume
runningWork.Set();
//
}
public void Work()
{
// long task
while (!stop)
{
runningWork.WaitOne(/* optional timeout */);
//worker task
}
}
我認為你沒有抓住重點。 不推薦使用Thread.Pause
和Thread.Resume
的原因是使用它們會導致一系列問題。 無論線程在做什么,調用Thread.Pause
暫停其軌道中的線程。 它可能拿着一把鎖。 只要它被掛起,它就會繼續持有那個鎖。 它可能在復制文件、執行數據庫更新、執行時間關鍵任務、更新共享數據結構等過程中。 、文件系統,甚至可能是處於不一致狀態的操作系統。 如果您隨后中止線程,就會使不一致的狀態永久化。
換句話說,不要那樣做。
如果您希望能夠暫停和恢復線程,則需要對線程進行編碼,使其知道可以暫停。 你需要讓它配合暫停。 因此,不是在其軌道上停止線程,而是告訴線程您希望它在最早的安全機會中停止。
我所知道的最簡單的方法是使用ManualResetEvent 。 這里的想法是您在設置狀態下初始化事件。 當您希望線程暫停時,您可以清除該事件。 然后當您希望線程恢復時再次設置它。 例如:
ManualResetEvent OkayToContinue = new ManualResetEvent(true);
// in your main thread
Thread myThread = CreateWorkerThread(...); // however you do that.
// pause the thread . . .
OkayToContinue.Reset();
// do whatever you want to do while the thread is suspended
// And then restart the thread
OkayToContinue.Set();
在工作線程中:
while (!done)
{
// make sure it's safe to continue
OkayToContinue.WaitOne();
// do next step . . .
}
現在,如果您希望線程終止,通常使用CancellationToken 。 為此,您將其添加到主程序中:
CancellationTokenSource CancelToken = new CancellationTokenSource();
通常,您CancelTokenSource.Token
傳遞給線程,以便它無法訪問 CancelletionTokenSource 對象,但對於本示例,我將通過父對象訪問它。
// in your thread proc
do
{
// do next step
// Then check to see if paused or canceled
OkayToContinue.WaitOne();
} while (!done && !CancelToken.Token.IsCancellationRequested);
這里的關鍵是你不是從線下拉出地毯。 相反,您是在告訴線程優雅地關閉。
private BackgroundWorker _bgWorker = new BackgroundWorker();
public void Main(string[] args)
{
_bgWorker.DoWork += _bgWorker_DoWork;
// We want to be able to cancel our installation, for whatever reason.
_bgWorker.SupportsCancellation = true;
_bgWorker.RunWorkerAsync();
}
private void _bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (!_bgWorker.CancellationPending)
{
// Do things for your install here.
}
// Display your dialog asking if they'd like to continue.
if (!userWantsToContinue)
{
// Do rollback logic here.
return;
}
else
{
// Do the rest of your install.
}
}
這是使用 BackgroundWorker 執行此操作的粗略拼湊示例,而不是您必須管理的單獨線程。 BackgroundWorker 還具有通過事件報告進度和通過事件報告線程工作完成的額外好處。
https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.