SoFunction
Updated on 2025-03-07

Winform multithreaded component uses BackgroundWorker

BackgroundWorker is a control used in ·net to perform multithreaded tasks. It allows programmers to perform some operations on a separate thread.

You can create a BackgroundWorker programmatically or drag it from the Components tab of the Toolbox onto the form. If you create a BackgroundWorker in Windows Forms Designer, it appears in the component bar and its properties appear in the Properties window.

Common methods

  • RunWorkerAsync starts performing background operations. Raises DoWork event.
    public void RunWorkerAsync(); //Start the thread and trigger the DoWork event
     public void RunWorkerAsync(object argument);
  • CancelAsync requests to cancel the pending background operation.
    Note: This method is to set the CancellationPending property to true, and will not terminate background operations. In background operations, check the CancellationPending property to decide whether to continue the time-consuming operation.
  • ReportProgress raises a ProgressChanged event.
    public void ReportProgress(int percentProgress); //Report progress and trigger the ProgressChanged event
     public void ReportProgress(int percentProgress, object userState);

Common properties

  • IsBusy: //Read-only attribute, used to determine whether the current thread is working.
  • CancellationPending: Indicates whether the application has requested cancellation of background operations. Read-only attribute, default is false, and the value is true when the CancelAsync method is executed.
  • WorkerSupportsCancellation: Indicates whether asynchronous cancellation is supported. To execute the CancelAsync method, you need to set the property to true first.
  • WorkerReportsProgress: Indicates whether progress can be reported. To execute the ReportProgress method, you need to set the property to true first.

Common events

  • DoWork: Occurs when the RunWorkerAsync method is called.
  • ProgressChanged: Optional, which occurs when the ReportProgress method is called.
  • RunWorkerCompleted: Optional, which occurs when the background operation has been completed, cancelled, or an exception is raised.

Notice: No user interface objects are operated in the DoWork event handler. Instead, communicate with the user interface through ProgressChanged and RunWorkerCompleted events.

If you want to communicate with the user interface controls in the DoWork event handler, you can use the ReportProgress method. ReportProgress (int percentProgress, object userState), can pass an object. The ProgressChanged event can obtain this information object from the UserState property of the parameter ProgressChangedEventArgs class. This event can also implement the progress bar function, presenting the progress of the task to the user in real time.

Simple programs are more convenient than Thread. It is more troublesome to communicate with controls on the user interface in Thread. You need to use delegates to call the Invoke or BeginInvoke methods of the control, and it is not as convenient as BackgroundWorker.

Steps to use backgroundWorker

  • Create a new BackgroundWorder object;

  • According to the requirements, set whether it can be cancelled (WorkerSupportsCancellation) and whether it can report progress (WorkerReportsProgress);

  • According to the needs, set up related events, DoWorker, ProgressChanged, ProgressChanged;

  • Call RunWorkerAsyns() method to start the thread;

  • At the location where it needs to be cancelled, judge the value of CancellationPending and perform relevant processing; // Optional

  • Call the ReportProgress(int percentProgress) method in the appropriate location to report the progress.

BackgroundWorker instance

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

             = true;//Report the completion progress             = true;//Allow users to terminate background thread                                                                //Binding event             += new DoWorkEventHandler(backgroundWorker1_DoWork);
             += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
             += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

        }
        //Start button        private void button1_Click(object sender, EventArgs e)
        {
            if (!)//Judge whether backgroundWorker1 is running asynchronous operations            {
                (1000);//Start the background asynchronous operation and call the DoWork event            }
            while ()//Waiting for the background to complete            {
                ();
            }
            ("Operation completed");
        }

        //Cancel button        private void button2_Click(object sender, EventArgs e)
        {
            if ( == true)
            {
                ();//Cancel background operation                ();//Release resources            }
        }

        //DoWork event declaration time-consuming operation to be performed        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker backgroundWorker = sender as BackgroundWorker;
             = ListNumber(backgroundWorker, e);//The operation result is saved (the RunWorkerCompleted event may be used)        }

        bool ListNumber(object sender, DoWorkEventArgs e)
        {
            int num = (int);//Receive incoming parameters, that is, the value passed in RunWorkerAsync(object argument)            for (int i = 1; i <= num; i++)
            {
                if ()//Discern whether the background operation has been requested. If it is false, exit                {
                     = true;// Whether the event should be canceled                    return false;
                }
                (10);//Execute a time-consuming operation                (i * 100 / num, i);//Report the completion progress
            }
            return true;
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

             = ;//Transfer the completion progress data to the progress bar             =  + "%";
            //Show the intermediate calculation results in the ListBox control            ();//Receive userState passed by the ReportProgress method        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ( == true) //Indicate whether the asynchronous operation has been cancelled            {
                ("Canceled!");
            }
            else if ( != null) // Indicates an error that occurs during asynchronous operation            {
                ("Error: " + );
            }
            else
            {
                (());  // Get the value of the result of the asynchronous operation, that is, the value set by Result in the DoWork event.            }

        }
    }

Make safe calls to Winform form controls

(The preferred method for implementing multithreading in WinForm is backgroundWorker)

Thread thread = new Thread(SetLabel);//Open another thread to set the properties of Label();
 
delegate void Action(string args);//Net3.5's own Action has no parameters and no return valueprivate void SetLabel()
{
    Action action = delegate (string args)
    {
        this. = args;
    };
    if ()//Discern whether the current code is running on the thread that created the control, or on another thread.        (action, "XXX");//Note that the Inovoke and BeginInvoke delegates of the control are both executed on the UI thread.  The Invoke method for Control can be used to delegate the MethodInvoker without parameters to return Void calls.    else
        action("XXX");
}

This is all about this article about BackgroundWorker, a winform multi-threaded component. I hope it will be helpful to everyone's learning and I hope everyone will support me more.