Pattern - Form OnClick

In this approach, instead of creating the plain old thread and using delegate to update the UI, we have BackgroundWorker component which does the work for us.
It supports multiple events to run long running process (DoWork), update the UI (ProgressChanged) and you will know when the background thread has actually ended (RunWorkerCompleted).
In the plain old thread, knowing the end of the thread is tricky and you have to rely either of Thread. Join or use some other wait handles.


Creating

Open Visual Studio 2022 as Administrator.
Create a New Project, language C#, platform Windows, project type Desktop.
Find "Windows Forms App" and press Next
Change the Project Name to "WinForms_Threading_BWOnClick".
Check / change the Location if necessary.
Press Next.
Check / Change the Framework to .NET 6.0.
Press Create.
This will create a solution that contains one project
SS
Displays the Toolbox and drag the following controls on to the Windows Form.
Button - Name="btnStart", Text="Start"
Button - Name="btnStop", Text="Stop"
Button - Name="btnCancel", Text="Cancel"
Label - Name="lblStopWatch", Text="Not Started"
SS
Add the following code to the Form1.cs file

namespace WinForms_Threading_BWOnClick 
{
    public partial class Form1 : Form
    {
        System.ComponentModel.BackgroundWorker? _workerThread = null;
        bool _keepRunning = false;

        public Form1()
        {
            InitializeComponent();

            method_InstantiateWorkerThread();
        }

        private void method_InstantiateWorkerThread()
        {
            this._workerThread = new System.ComponentModel.BackgroundWorker();
            this._workerThread.DoWork += method_WorkerThread_DoWork;

            this._workerThread.WorkerReportsProgress = true;
            this._workerThread.ProgressChanged += method_WorkerThread_ProgressChanged;

            this._workerThread.RunWorkerCompleted += method_WorkerThread_RunWorkerCompleted;
            this._workerThread.WorkerSupportsCancellation = true;
        }

        private void method_WorkerThread_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            System.DateTime startTime = DateTime.Now;
            this._keepRunning = true;

            while (this._keepRunning)
            {
                System.Threading.Thread.Sleep(1000);
                string timeElapsedInstring = (System.DateTime.Now - startTime).ToString(@"hh\:mm\:ss");
                this._workerThread.ReportProgress(0, timeElapsedInstring);

                if (this._workerThread.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
            }
        }

        private void method_WorkerThread_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
            this.lblStopWatch.Text = e.UserState.ToString();
        }

        private void method_WorkerThread_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                this.lblStopWatch.Text = "Cancelled";
            }
            else
            {
                this.lblStopWatch.Text = "Stopped";
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            this._workerThread.RunWorkerAsync();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            this._keepRunning = false;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this._workerThread.CancelAsync();
            this.Close();
        }
    }
}

Running

Build the solution and press F5.
When the Windows Form is displayed press the Start Button.
A counter will start and be displayed in the Label control.
Press the Stop Button to stop the counter.
Press the Cancel Button to close the Windows Form.


© 2024 Better Solutions Limited. All Rights Reserved. © 2024 Better Solutions Limited TopPrevNext