17

I need to be able to continuously run my BackgroundWorker. The DoWork event contains a pool threaded process and the OnComplete updates my UI.

I have not been able to find a way to infinitely loop the BackgroundWorker.RunWorkerAsync() method without the whole program freezing. Any help would be greatly appreciated.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
user2952817
  • 223
  • 1
  • 3
  • 8
  • 1
    What do you want to do with your `BackgroundWorker`? Why do you want it to run continuously? – King King Nov 04 '13 at 14:14
  • 1
    Why not just use "regular" threading then? Or maybe tasks or whatever.. Why exactly you need BackgroundWorker? AFAIK it wasn't meant to be used like this, ever. – walther Nov 04 '13 at 14:15
  • 1
    You can communicate back to the primary thread (UI) and keep BackgroundWorker running with ReportsProgress. – paparazzo Nov 04 '13 at 14:15
  • The background worker is running a class that runs a multi-threaded process with each thread pinging a server. I want the process to always be runnning and feeding data to the UI for as long as the application is running – user2952817 Nov 04 '13 at 14:18
  • you should just add items to the BGWorker/ThreadPool when you need to. There shouldn't be a whole "continuously" running scenario here. – Ahmed ilyas Nov 04 '13 at 14:51

5 Answers5

29

You have to make a loop in your DoWork-Method. To update your UI you shoud use the ProgressChanged-Method. Here is a small example how this can look like

 public Test()
    {
        this.InitializeComponent();
        BackgroundWorker backgroundWorker = new BackgroundWorker
            {
                 WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            };
        backgroundWorker.DoWork += BackgroundWorkerOnDoWork;
        backgroundWorker.ProgressChanged += BackgroundWorkerOnProgressChanged;
    }

    private void BackgroundWorkerOnProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        object userObject = e.UserState;
        int percentage = e.ProgressPercentage;
    }

    private void BackgroundWorkerOnDoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = (BackgroundWorker) sender;
        while (!worker.CancellationPending)
        {
            //Do your stuff here
            worker.ReportProgress(0, "AN OBJECT TO PASS TO THE UI-THREAD");
        }        
    }
Tomtom
  • 9,087
  • 7
  • 52
  • 95
  • 5
    Instead of `while(true)` use `((BackgroundWorker)sender).CancellationPending` and you support cancellation. – CodeZombie Nov 04 '13 at 14:25
  • 1
    The logic needs to be flipped on that though. CancellationPending is false initially and becomes true when the user wants to cancel it. So the loop should be checking `!worker.CancellationPending` – Chris Nov 04 '13 at 14:40
9

I have done this in the past when needing something to run in the background. If you try to run the backgroundworker while it is running, you will get an excpetion! That is why i make the BackGroundWorker start itself when it is done in the completed event.

And then it will loop forever.

private void Main_Load(object sender, EventArgs e)
{
   // Start Background Worker on load
   bgWorker.RunWorkerAsync();
}

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
   Thread.Sleep(1000);   // If you need to make a pause between runs
   // Do work here
}

private void bgCheck_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Update UI

// Run again
bgWorker.RunWorkerAsync();   // This will make the BgWorker run again, and never runs before it is completed.
}
Niels Schmidt
  • 383
  • 3
  • 7
  • 1
    Instead of just starting it over ever time it finishes, why not just have a while(true) loop so it runs infinitely? – bkribbs May 26 '15 at 18:50
  • 2
    Worked flawlessly ! Its implementation was easier than a timer and do its job without locking the UI ! Thanks a lot, great method :) ! Should be marked as answer. – Pablo Costa Mar 14 '16 at 01:34
  • --bkribs Because this way you can also add code in "ProgressUpdated" and "WorkerCompleted" if you need to update UI elements :) – Niels Schmidt Mar 15 '16 at 05:54
0
 timer.interval=60000 // 1 min

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        timer1.Start();

    }
 private void timer1_Tick(object sender, EventArgs e)
    {
        try
        {
           //Do something
        }
        catch
        {


        }
    }
Alen Smith
  • 35
  • 8
  • 2
    Always a good idea to include some form of detail or description for why your answer works instead of just code. – Charlie Fish Aug 09 '16 at 17:41
  • 2
    While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, as this reduces the readability of both the code and the explanations! – Blue Aug 09 '16 at 23:57
0

on backgroundworker completed event, just start background worker again

  • how is this answer different from that of Niels Schmidt? – Mong Zhu Feb 06 '23 at 07:17
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/33768225) – Elijah Mock Feb 09 '23 at 00:13
-2

If your program is freezing, it may be because your infinitely looping background worker thread is spinning, using 100% CPU. You haven't said why you need it to run in an infinite loop, but you could start by putting a Thread.Sleep in that loop.

Joe
  • 122,218
  • 32
  • 205
  • 338
  • 1
    Thread.Sleep is bad practice and shouldn't be put in for production. The problem seems to be some other while loop going on such as perhaps while(true). Threading should be used when a long running task is to be run and then will finish. there is no reason to keep the thread running even if the task is finished. you need to let things "happen naturally" as they say. – Ahmed ilyas Nov 04 '13 at 14:50
  • @Ahmedilyas - I didn't suggest putting anything into production. I think a BackgroundWorker that is running an infinite loop is a questionable practice, but putting in a Thread.Sleep might get the OP beyond the "application freezing" problem, and into a position to think more about his design. He hasn't said why he wants an infinite loop, so it's difficult to suggest what alternatives might be more appropriate. – Joe Nov 04 '13 at 14:55
  • Note that 'infinite loop' does not mean 100% CPU use, in general, in multithreaded apps - usually, they block on something. Also, THIS USE of Thread.Sleep is indeed bad practice, but it has legitimate uses. – Martin James Nov 04 '13 at 15:14
  • @MartinJames - Seem to be getting downvotes for this. Of course I agree with you that an infinite loop does not mean 100% CPU, but if someone says they can't get an infinite loop working without the whole program freezing, inserting a Sleep might help them understand why. And hopefully, once they understand why, they'll be able to design a better solution that doesn't need a Sleep. – Joe Nov 04 '13 at 15:55