简体   繁体   English

如何一遍又一遍地启动和停止后台线程?

[英]How do I start and stop background thread over and over again?

I have c# app that has UI and background threads.我有具有 UI 和后台线程的 c# 应用程序。 Based on user input I like to stop and start the background thread.根据用户输入,我喜欢停止和启动后台线程。 I have two options here as I see:正如我所见,我在这里有两个选择:

1) totally stop and then start background thread as new thread ( I have not been able to this. I keep getting my process ended message) 1)完全停止,然后将后台线程作为新线程启动(我无法做到这一点。我一直收到我的进程结束消息)

2) Pause the background thread until user click run again. 2)暂停后台线程,直到用户再次单击运行。

Here is the code that I call again after bw.CancelAsync();这是我在 bw.CancelAsync() 之后再次调用的代码;

    private void StartBackgroundWorker()
    {
        bw = new BackgroundWorker();
        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.RunWorkerAsync("Background Worker");
    }

you can't start and stop a background worker like that, but in your DoWork event, you can have it ask whether it should execute or wait.您不能像那样启动和停止后台工作程序,但是在您的 DoWork 事件中,您可以让它询问它是应该执行还是等待。

you can also subclass BackgroundWorker (override the OnDoWork() method), and add start/pause methods to it that toggle a private wait handle, which is much nicer than having your UI know about the ManualResetEvent.您还可以子类化 BackgroundWorker(覆盖 OnDoWork() 方法),并向其添加启动/暂停方法以切换私有等待句柄,这比让您的 UI 了解 ManualResetEvent 好得多。

//using System.Threading;

//the worker will ask this if it can run
ManualResetEvent wh = new ManualResetEvent(false);

//this holds UI state for the start/stop button
bool canRun = false;

private void StartBackgroundWorker()
{
    bw = new BackgroundWorker();
    bw.WorkerReportsProgress = true;
    bw.WorkerSupportsCancellation = true;
    bw.DoWork += bw_DoWork;
    bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    bw.RunWorkerAsync("Background Worker");
}


void bw_DoWork(object sender, DoWorkEventArgs e)
{
     while(true) 
     {
          //it waits here until someone calls Set() on wh  (via user input)
          // it will pass every time after that after Set is called until Reset() is called
          wh.WaitOne()

         //do your work

     }
}


//background worker can't start until Set() is called on wh
void btnStartStop_Clicked(object sender, EventArgs e)
{
    //toggle the wait handle based on state
    if(canRun)
    {
        wh.Reset();
    }
    else {wh.Set();}

    canRun= !canRun;
    //btnStartStop.Text = canRun ? "Stop" : "Start";
}

You can always abort a thread and catch the ThreadAbortedException.您始终可以中止线程并捕获 ThreadAbortedException。 Im not sure if this is the most neat solution since an exception causes a lot of overhead but i think it is better than spreading WaitOne in the code like Dan suggested.我不确定这是否是最简洁的解决方案,因为异常会导致大量开销,但我认为这比像 Dan 建议的那样在代码中传播 WaitOne 更好。

Another solution is to inherit from the thread class, and add a function to this class that stops or pauses the thread.另一种解决方案是从线程类继承,并在该类中添加一个停止或暂停线程的函数。 This way you can hide the details of the implementation.这样你就可以隐藏实现的细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM