Backgroundworker to stop work after specified time

1.1k views Asked by At

I have went over dozens of question and tutorial but ended up with nothing so I hope to get help of you guys.

I have a BW, doing some heavy work (rading up services, saving them into a file). BW is initialized at run time, and fired up with button click. This works perfectly, but thing is it works non-stop or till event btn_cancel get's clicked which stops the BW.

What I want to achieve is to start my bw_doWork again with button click, but work only for specified period of time. For the first time, it takes up to 30 secs to doWork() to finish, then around 10. I have tried to use Stop Watch but with no success so far.

My code so far looks like this:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // Do not access the form's BackgroundWorker reference directly. 
        // Instead, use the reference provided by the sender parameter.
        long targetTime = (long) e.Argument;
        Stopwatch sw = new Stopwatch();

        if (targetTime > 0)
        {
            sw.Start();
        }

        while (true)
        {
            if ((targetTime > 0) && (sw.ElapsedMilliseconds >= targetTime))
            {
                BackgroundWorker bw = sender as BackgroundWorker;
                while (!bw.CancellationPending)
                {
                    GetServicesToFile();

                }
            sw.Reset();
            sw.Start();
            }

        }           
    }

btn_Click

private void btnServiceLoad_Click(object sender, EventArgs e)
        {
           // sw.Start();
            if (backgroundWorker1.IsBusy != true)
            {
                this.backgroundWorker1.RunWorkerAsync();
            }
            ReadServicesFromFile();
        }
1

There are 1 answers

0
Robert Synoradzki On BEST ANSWER

Managed this with a System.Windows.Forms.Timer which starts along with BackgroundWorker, whose delay you initialise freely, and whose first Tick event cancels BackgroundWorker. You can also cancel with a button. Does that help?

Just started After some work

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;



public partial class TimedBGWTest:Form {
    static int p=0;
    static Timer t;

    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TimedBGWTest());
    }

    public TimedBGWTest() {
        InitializeComponent();

        t=new Timer() { Interval=2000 };
        t.Tick+=t_Tick;
    }



// Buttons
    private void buttonStart_Click(object sender,EventArgs e) {
        t.Stop();
        t.Start();
        if(bgw.IsBusy) return;
        buttonCancel.BackColor=Color.IndianRed;
        buttonCancel.Enabled=true;
    }

    private void buttonCancel_Click(object sender,EventArgs e) {
        bgw.CancelAsync();
        t.Stop();
    }

// Timer
    void t_Tick(object sender, EventArgs e) {
        bgw.CancelAsync();
        (sender as Timer).Stop();
    }

// Background worker
    private void bgw_DoWork(object sender,DoWorkEventArgs e) {
        while(!bgw.CancellationPending) {
            if(++p>100) p=0;
            bgw.ReportProgress(p);
            System.Threading.Thread.Sleep(200);
        }
    }

    private void bgw_ProgressChanged(object sender,ProgressChangedEventArgs e) {
        progressBar1.Value=e.ProgressPercentage;
    }

    private void bgw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e) {
        buttonCancel.BackColor=Color.LightGray;
        buttonCancel.Enabled=false;
    }
}

GUI code for file .Designer.cs available at http://ideone.com/PcvCRB