mrcavanaugh09
mrcavanaugh09

Reputation: 363

Having trouble with background worker processes in WPF application

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

Upvotes: 0

Views: 69

Answers (3)

Enigmativity
Enigmativity

Reputation: 117019

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.

Upvotes: 1

jegtugado
jegtugado

Reputation: 5141

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
    }

Upvotes: 2

Andy
Andy

Reputation: 30418

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.

Upvotes: 0

Related Questions