簡體   English   中英

C#從主線程暫停一個工作線程

[英]C# Pause a working thread from the main thread

所以,我想從主線程暫停一個工作線程,如果我決定,我希望能夠恢復它的活動。 之前,我使用了myThread.Suspend()Resume()但它已被棄用不建議再使用它。

你們中的任何人都可以給我一個替代方案嗎? 謝謝!

一種方法是使用ManualResetEventAutoResetEvent對象。 等待信號的線程將被阻塞,直到某事將在事件對象上調用 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.PauseThread.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.

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