Call backgroundWorker

YUI-012 20 Reputation points
2024-09-09T12:44:37.9333333+00:00

I creating simple permutation code using c# app. Now I want to display a simple progressbar. Now if the program execute I want to check if the background is busy else I call the backgroundworker and show how many percent remaining.

The code below I call when permutation code is execute.

static IEnumerable<IEnumerable<int>> GetPermutations(IEnumerable<int> indices, int limit)
        {
            if (limit == 1)
            {
                foreach (var index in indices)
                    yield return new[] { index };
                yield break;
            }

            var indicesList = indices.ToList();
            var subPermutations = GetPermutations(indices, limit - 1);

            foreach (var index in indicesList)
            {
                foreach (var subPerm in subPermutations)
                {
                    if (!subPerm.Contains(index))
                    {
                        yield return subPerm.Append(index);

                        //Cursor.Current = Cursors.WaitCursor;//for waiting..

                        //try
                        if (backgroundWorker1.IsBusy != true)
                        {
                            // Start the asynchronous operation.
                            backgroundWorker1.RunWorkerAsync();
                        }

                    }
                }
            }
        }


and this is the backgroundworker do work code.

private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
      {
          BackgroundWorker worker = sender as BackgroundWorker;

          for (int i = 1; i <= 10; i++)
          {
              if (worker.CancellationPending == true)
              {
                  e.Cancel = true;
                  break;
              }
              else
              {
                  // Perform a time consuming operation and report progress.
                  System.Threading.Thread.Sleep(500);
                  worker.ReportProgress(i * 10);
              }
          }
      }

My problem is, I dont know how to call backgroundWorker1 inside in static method.

 image

Visual Studio
Visual Studio
A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.
5,059 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,858 questions
{count} votes

Accepted answer
  1. Jiale Xue - MSFT 44,751 Reputation points Microsoft Vendor
    2024-09-09T13:33:23.4766667+00:00

    Hi @YUI-012 , Welcome to Microsoft Q&A,

    In the current code, RunWorkerAsync() may be called every time the arrangement is generated, which will cause an exception because BackgroundWorker cannot run multiple tasks in parallel. Therefore, you should make sure to start the BackgroundWorker when starting the arrangement calculation, rather than checking it every time the arrangement is generated. In order to update the UI in real time during the arrangement generation process, you can update the ListBox or other controls through the ProgressChanged event. Be careful to avoid directly operating the UI in the DoWork event, because cross-thread operations will cause exceptions.

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Forms;
    namespace _xxx
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                backgroundWorker1.WorkerReportsProgress = true;
                backgroundWorker1.WorkerSupportsCancellation = true;
            }
            static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> items, int limit, BackgroundWorker worker)
            {
                if (limit <= 0 || items == null)
                    yield break;
                var itemsList = items.ToList();
                var indices = Enumerable.Range(0, itemsList.Count);
                foreach (var indicesPerm in GetPermutations(indices, limit, worker))
                {
                    yield return indicesPerm.Select(i => itemsList[i]);
                }
            }
            static IEnumerable<IEnumerable<int>> GetPermutations(IEnumerable<int> indices, int limit, BackgroundWorker worker)
            {
                int totalPermutations = Factorial(indices.Count()) / Factorial(indices.Count() - limit);
                int currentPermutation = 0;
                if (limit == 1)
                {
                    foreach (var index in indices)
                    {
                        currentPermutation++;
                        if (worker.CancellationPending)
                            yield break;
                        var permutation = new[] { index };
                        worker.ReportProgress((currentPermutation * 100) / totalPermutations, permutation);
                        yield return permutation;
                    }
                    yield break;
                }
                var indicesList = indices.ToList();
                var subPermutations = GetPermutations(indices, limit - 1, worker);
                foreach (var index in indicesList)
                {
                    foreach (var subPerm in subPermutations)
                    {
                        if (!subPerm.Contains(index))
                        {
                            currentPermutation++;
                            if (worker.CancellationPending)
                                yield break;
                            var permutation = subPerm.Append(index);
                            worker.ReportProgress((currentPermutation * 100) / totalPermutations, permutation);
                            yield return permutation;
                        }
                    }
                }
            }
            // Helper method to calculate factorial
            static int Factorial(int n)
            {
                return (n == 1 || n == 0) ? 1 : n * Factorial(n - 1);
            }
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                BackgroundWorker worker = sender as BackgroundWorker;
                string[] items = textBox2.Text.Split(' ');
                // Get the limit.
                int limit = int.Parse(textBox1.Text);
                // Generate permutations
                var permutations = GetPermutations(items, limit, worker);
                // Collect permutations in a list to return it as the result.
                var permutationList = new List<IEnumerable<string>>();
                foreach (var perm in permutations)
                {
                    if (worker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }
                    permutationList.Add(perm);
                }
                // Store the result in the DoWorkEventArgs
                e.Result = permutationList;
            }
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                // Update the progress bar with the percentage reported
                progressBar1.Value = e.ProgressPercentage;
                // Output the current permutation to ListBox
                var currentPermutation = (IEnumerable<int>)e.UserState;
                listBox1.Items.Add(string.Join(" ", currentPermutation));
            }
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Cancelled)
                {
                    MessageBox.Show("Operation was cancelled.");
                }
                else if (e.Error != null)
                {
                    MessageBox.Show("Error: " + e.Error.Message);
                }
                else
                {
                    // Clear the ListBox and display all permutations
                    listBox1.Items.Clear();
                    // Access the permutations from the result
                    var permutations = (List<IEnumerable<string>>)e.Result;
                    foreach (var permutation in permutations)
                    {
                        listBox1.Items.Add(string.Join(" ", permutation));
                    }
                    MessageBox.Show("Operation completed.");
                }
            }
            private void Btngenerate_Click(object sender, System.EventArgs e)
            {
                if (!backgroundWorker1.IsBusy)
                {
                    // Clear the previous results.
                    listBox1.Items.Clear();
                    // Start the background worker asynchronously.
                    backgroundWorker1.RunWorkerAsync();
                }
                else
                {
                    MessageBox.Show("Already generating permutations.");
                }
            }
        }
    }
    
    

    User's image

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.