2

I have WPF application where in the Ui I have a header check box and when it is checked all the body checkboxes are checked. When any checkbox is checked, Im doing some work that I need by calling the Background worker which works perfect. If I select any checkboxes individually without checking header then Background worker works fine.

Problem is when I check the header all the body checkboxes are checked and in this case the Background worker 'Run Worker completed' event is being executed even before 'do work' is executed which is breaking my code. Please help. Here is my code. RunJob is from command for button in front end.

public void RunJob(object obj)
        {
            obforSave = obj;
            workerforRun = new BackgroundWorker();
            workerforRun.WorkerReportsProgress = true;
            workerforRun.DoWork += workerforRun_DoWork;
            workerforRun.ProgressChanged += workerforRun_ProgressChanged;
            workerforRun.RunWorkerCompleted += workerforRun_RunWorkerCompleted;
            if (!workerforRun.IsBusy)
            {
                workerforRun.RunWorkerAsync();
            }
        }

        //Special case header is checked Runwroker completed is executing before do work.
        void workerforRun_DoWork(object sender, DoWorkEventArgs e)
        {
            IsValidationsComplete = false;
            int count = 0;
            //var obj = e.Argument;
            if (IsRunJobAlreadyExecuted == false)
            {
                ResultExtract = JobEntities.Any(s => s.ExtractIsSelected != null && (bool)s.ExtractIsSelected);
                var resultTransform = JobEntities.Any(x => x.TransformIsSelected != null && (bool)x.TransformIsSelected);
                var resultLoad = JobEntities.Any(b => b.LoadIsSelected != null && (bool)b.LoadIsSelected);
                //Check if any of the entities are either Extracted, Transformed or Loaded.
                if (ResultExtract || resultTransform || resultLoad)
                {
                    SaveJobConfigurationChanges(obforSave);
                    var jobEngine = new JobEngine();
                    var jobId = JobEntities[0].JobId;
                    jobEngine.ProcessJob(jobId);
                    MessageBox.Show("Job Execution Complete", "Run Job");
                    AllResults = GetJobConfigurationResults();
                    foreach (var item in AllResults)
                    {
                        if (item.ExtractIsSelected == true && item.ExtractStatus == "Completed Successfully")
                        {
                            count += Convert.ToInt32(item.ExtractRowsSelected);
                        }
                        if (item.TransformIsSelected == true && item.TransformStatus == "Completed Successfully")
                        {
                            count += Convert.ToInt32(item.TransformRowsSelected);
                        }
                        if (item.LoadIsSelected == true && item.LoadStatus == "Completed Successfully")
                        {
                            count += Convert.ToInt32(item.LoadRowsSelected);
                        }
                    }

                    workerforRun.ReportProgress(count);
                    //MessageBox.Show(count.ToString());
                }
                else
                {
                    //When No Entity is Selected and the Run Button is pressed.
                    MessageBox.Show("Select an Entity First");

                }
            }
            IsRunJobAlreadyExecuted = false;
        }


        void workerforRun_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progress = e.ProgressPercentage;
        }

        void workerforRun_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                /*When Header is checked and when the Run is clicked, you want to Uncheck the header back after completion.
            This property is set in the CS file.*/
                AllResults = GetJobConfigurationResults();
                foreach (var item in AllResults)
                {
                    item.ExtractIsSelected = false;
                    item.TransformIsSelected = false;
                    item.LoadIsSelected = false;
                }
                SaveTaskSelection();
                JobEntitiesCollectionViewSource.Source = AllResults;
                JobEntitiesCollectionViewSource.View.Refresh();
                ExecuteFilteredEntitiesStoredProcedure();
                IsValidateEnabled = AllResults.Any(p => p.ExtractStatus == "Completed Successfully");
            }), DispatcherPriority.Background, null);
            MessageBox.Show(progress.ToString());
            IsValidationsComplete = true;
        }


CS file:

    public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    var child = VisualTreeHelper.GetChild(depObj, i);
                    // If there is a child found and if the child is of the T type. 
                    //Dont remove null check . If no check i
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }
                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }

private IEnumerable<CheckBox> GetAllCheckBoxs()
        {
            var allCheckBoxes = FindVisualChildren<CheckBox>(UserControlJob);
            return allCheckBoxes;
        }

private void ChkHeaderExtract_OnChecked(object sender, RoutedEventArgs e)
        {
                var extractCheckBoxes = GetAllCheckBoxs();
                var i = 0;
                foreach (var chk in extractCheckBoxes)
                {
                    if (i%3 == 0) // Since I have many sets of checkboxes and I want only the first set of checkboxes checked when header is clicked Im doing this.
                    {
                        chk.IsChecked = true;
                    }
                    i++;
                }

            }
nikhil
  • 1,578
  • 3
  • 23
  • 52
  • 1
    At a guess, it might be your RunJob that is being called multiple times.....and it is "reusing" the workerforRun member variable without checking if the previous BackgroundWorker has completed yet....thus when the previous one is garbage collected it appears to raise a completed event before your new BackgorundWorker has started...so the completed event you are seeing is for the previous one?.... Do a assert(sender == workerforRun) in your workerforRun_RunWorkerCompleted to confirm this. Also check RunWorkerCompletedEventArgs.Result to see if it says cancelled/exception. – Colin Smith Feb 11 '15 at 19:29
  • Post the code where you call this runjob when you check the checkboxes. This helps to solve your problem – Sievajet Feb 11 '15 at 22:22
  • Thanks Colin Smith and Sievajet you are right I was calling the RunJob from cs file as well which is preventing the execution of do work. Thanks again i will work on that. – nikhil Feb 11 '15 at 22:42
  • I would suggest a solution with only one worker otherwise you'll need to look into synchronization – Sievajet Feb 15 '15 at 17:16

0 Answers0