0

I found a few other articles regarding using background worker which I've linked just below. I used the code examples and attempted to do this to run 3 different SQL Query's. In the code posted below when I break inside of RunBackGroundWorkerProcesses1 it does stop there and is called but method for worker_DoWork1 is never called even though it is in the code. I'm assuming that I've misunderstood this, can someone add some clarity.

Link I used for reference: WPF Multithreading

Code:

public CallInformationMainScreen()
        {
            InitializeComponent();    

//This is where i call the background processes
            RunBackGroundWorkerProcesses1();
            RunBackGroundWorkerProcesses2();
            RunBackGroundWorkerProcesses3();    
        }
        #endregion

        #region Methods used to generate data for the UI
        public string DisplayTotalDailyCalls()
        {
            DailyCallsQuery db = new DailyCallsQuery();
            return db.GetNumber(SkillNumber);
        }
        public string DisplayTotalLastSevenCalls()
        {
            PrevSevenCallQuery db = new PrevSevenCallQuery();
            return db.GetNumber(SkillNumber);
        }
        public string DisplayDailyAbandonCalls()
        {
            DailyAbandonQuery db = new DailyAbandonQuery();
            return db.GetNumber(SkillNumber);
        }    


        #endregion

        #region Background worker processes        
        private void RunBackGroundWorkerProcesses1()
        {
            BackgroundWorker worker = new BackgroundWorker();            
            worker.DoWork += new DoWorkEventHandler(worker_DoWork1);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

            System.Timers.Timer t = new System.Timers.Timer(10000); //  10 second intervals
            t.Elapsed += (sender, e) =>
            {
                // Don't try to start the work if it's still busy with the previous run...
                if (!worker.IsBusy)
                    worker.RunWorkerAsync();
            };
        }
        private void RunBackGroundWorkerProcesses2()
        {
            BackgroundWorker worker = new BackgroundWorker();           
            worker.DoWork += new DoWorkEventHandler(worker_DoWork2);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

            System.Timers.Timer t = new System.Timers.Timer(10000); //  10 second intervals
            t.Elapsed += (sender, e) =>
            {
                // Don't try to start the work if it's still busy with the previous run...
                if (!worker.IsBusy)
                    worker.RunWorkerAsync();
            };
        }
        private void RunBackGroundWorkerProcesses3()
        {
            BackgroundWorker worker = new BackgroundWorker();            
            worker.DoWork += new DoWorkEventHandler(worker_DoWork3);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

            System.Timers.Timer t = new System.Timers.Timer(10000); //  10 second intervals
            t.Elapsed += (sender, e) =>
            {
                // Don't try to start the work if it's still busy with the previous run...
                if (!worker.IsBusy)
                    worker.RunWorkerAsync();
            };
        }

        private void worker_DoWork1(object sender, DoWorkEventArgs e)
        {
            // Whatever comes back from the lengthy process, we can put into e.Result            
            TotalDailyCalls = DisplayTotalDailyCalls();
            e.Result = TotalDailyCalls;
        }
        private void worker_DoWork2(object sender, DoWorkEventArgs e)
        {
            // Whatever comes back from the lengthy process, we can put into e.Result            
            TotalDailyLast7Days = DisplayTotalLastSevenCalls();
            e.Result = TotalDailyCalls;
        }
        private void worker_DoWork3(object sender, DoWorkEventArgs e)
        {
            // Whatever comes back from the lengthy process, we can put into e.Result
            TotalDailyAbandon = DisplayDailyAbandonCalls();
            e.Result = TotalDailyAbandon;
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // First, handle the case where an exception was thrown.
            if (e.Error != null)
            {
                // handle the System.Exception
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                // now handle the case where the operation was cancelled... 
                ErrorHolder = "The operation was cancelled";
            }
            else
            {
                // Finally, handle the case where the operation succeeded
                ErrorHolder = e.Result.ToString();
            }
        }
        #endregion
Community
  • 1
  • 1
mrcavanaugh09
  • 333
  • 1
  • 3
  • 14
  • What is it that you're trying to do with this code? Is it simply that you're trying to repeatedly run each of these three queries in the background? – Enigmativity May 17 '17 at 02:59
  • yes the numbers are calls coming into call queue and will update every few minutes. i was going to adjust the time after i got it to at least function which it looks like it is doing now thanks to the answer below and the simple timer start that i missed. – mrcavanaugh09 May 17 '17 at 03:01
  • There's a far simply way to do this. I'll pop an answer in for you to show you. – Enigmativity May 17 '17 at 03:07

3 Answers3

2

You don't start your timers. See Timer.Start Method ().

    private void RunBackGroundWorkerProcesses1()
    {
        BackgroundWorker worker = new BackgroundWorker();            
        worker.DoWork += new DoWorkEventHandler(worker_DoWork1);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

        System.Timers.Timer t = new System.Timers.Timer(10000); //  10 second intervals
        t.Elapsed += (sender, e) =>
        {
            // Don't try to start the work if it's still busy with the previous run...
            if (!worker.IsBusy)
                worker.RunWorkerAsync();
        };
        t.Start(); // Start the timer
    }
jegtugado
  • 5,081
  • 1
  • 12
  • 35
1

I'm posting this to demonstrate an easier way to do this. It's not meant to be a direct answer to the question.

If you NuGet "System.Reactive" and the associated WPF libraries you can do this:

IDisposable subscription =
    new []
    {
        Observable.Interval(TimeSpan.FromSeconds(10.0)).Select(x => DisplayTotalDailyCalls()),
        Observable.Interval(TimeSpan.FromSeconds(10.0)).Select(x => DisplayTotalLastSevenCalls()),
        Observable.Interval(TimeSpan.FromSeconds(10.0)).Select(x => DisplayDailyAbandonCalls()),
    }
    .Merge()
    .ObserveOnDispatcher()
    .Subscribe(x => ErrorHolder = x, e => MessageBox.Show(e.Error.Message));

That's it. Job done. All of your code in techically one line of code.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • holy crap. lol. Just to understand this correctly, that replaces all three of my background worker methods? And this still allows them to operate as a background process? The reason for all this is because each time one of these SQL methods were triggered it would lock the application. so i need to be sure that the querys are happening as a background process. – mrcavanaugh09 May 17 '17 at 03:22
  • actually this will also replace my completed and all my dowork methods too. wow. – mrcavanaugh09 May 17 '17 at 03:25
  • 1
    @mrcavanaugh09 - Yes, that's correct. All in the background. All with a 10 second gap between each run, all running in parallel, and all replacing all the methods in your code. – Enigmativity May 17 '17 at 04:08
  • 1
    @mrcavanaugh09 - If you want to stop the code running just call `subscription.Dispose();`. – Enigmativity May 17 '17 at 04:08
0

BackgroundWorker.RunWorkerAsync() is only called when the Timer.Elapsed event is fired. Since the timer is set to 10 second intervals, the BackgroundWorker won't start for 10 seconds. You probably should call BackgroundWorker.RunWorkerAsync() after creating and initializing it so that it will start right away.

Andy
  • 30,088
  • 6
  • 78
  • 89
  • backgroundworker.runworkerasync() is called in the if statement in each method already. I've also waited minutes with the application running and none of the SQL Query methods are being hit. – mrcavanaugh09 May 17 '17 at 02:15