MULTITHREADED WINDOWS APPLICATION IN C#

HAI

IM USING A STATUS BAR WHERE IM DISPLAYING TIME

AND I NEED THE TIME TO GET UPDATED

BUT AT THE SAME TIME THE USER MUST BE ABLE TO DO OTHER INPUTS IN THE SAME FORM

ALSO I NEED TO UPDATE DATABASE IN THE BACKGROUND

I GUESS THIS COULD BE DONE USING MULTITHREADING

WILL SOME ONE HELP ME??????
LVL 1
VijayDixonAsked:
Who is Participating?
 
AlexFMConnect With a Mentor Commented:
The same using BackgroundWorker class. To make this sample working, create C# Windows Forms application. Paste this code to Form1.Designer.cs replacing existing code:

namespace WorkerThread1
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.listBox1 = new System.Windows.Forms.ListBox();
            this.btnStart = new System.Windows.Forms.Button();
            this.btnStop = new System.Windows.Forms.Button();
            this.backWorker = new System.ComponentModel.BackgroundWorker();
            this.SuspendLayout();
            //
            // listBox1
            //
            this.listBox1.FormattingEnabled = true;
            this.listBox1.Location = new System.Drawing.Point(16, 10);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(323, 173);
            this.listBox1.TabIndex = 0;
            //
            // btnStart
            //
            this.btnStart.Location = new System.Drawing.Point(53, 189);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(99, 28);
            this.btnStart.TabIndex = 1;
            this.btnStart.Text = "Start";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            //
            // btnStop
            //
            this.btnStop.Location = new System.Drawing.Point(211, 189);
            this.btnStop.Name = "btnStop";
            this.btnStop.Size = new System.Drawing.Size(99, 28);
            this.btnStop.TabIndex = 2;
            this.btnStop.Text = "Stop";
            this.btnStop.UseVisualStyleBackColor = true;
            this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
            //
            // backWorker
            //
            this.backWorker.WorkerReportsProgress = true;
            this.backWorker.WorkerSupportsCancellation = true;
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(353, 229);
            this.Controls.Add(this.btnStop);
            this.Controls.Add(this.btnStart);
            this.Controls.Add(this.listBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.ListBox listBox1;
        private System.Windows.Forms.Button btnStart;
        private System.Windows.Forms.Button btnStop;
        private System.ComponentModel.BackgroundWorker backWorker;
    }
}

Paste this code to Form1.cs replacing existing code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WorkerThread1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Application.Idle += new EventHandler(Application_Idle);

            InitializeBackgroundWorker();
        }

        /// <summary>
        /// Set state of controls.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Application_Idle(object sender, EventArgs e)
        {
            // Start: enebled if background worker is not busy (not running)
            btnStart.Enabled = (! backWorker.IsBusy);

            // Stop: enabled if background worker is busy, but not
            // waiting for cancellation.
            btnStop.Enabled = (backWorker.IsBusy  &&
                ! backWorker.CancellationPending );
        }

        /// <summary>
        /// Subscribe to background worker events.
        /// </summary>
        private void InitializeBackgroundWorker()
        {
            backWorker.DoWork += new DoWorkEventHandler(backWorker_DoWork);
            backWorker.ProgressChanged += new ProgressChangedEventHandler(backWorker_ProgressChanged);
            backWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backWorker_RunWorkerCompleted);
        }

        /// <summary>
        /// Start background work.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();

            backWorker.RunWorkerAsync(10);      // 10 is number of steps
        }

        /// <summary>
        /// Stop background work asynchronously
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, EventArgs e)
        {
            backWorker.CancelAsync();
        }

        /// <summary>
        /// If background work is executed,
        /// stop it synchronously.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if ( ! backWorker.IsBusy )
                return;

            // Cancel synchronously (ask and wait)

            this.Enabled = false;       // prevent any user actions

            backWorker.CancelAsync();   // ask to stop

            // Wait when it really stops
            int i = 0;

            while ( backWorker.IsBusy )
            {
                System.Threading.Thread.Sleep(100);
                Application.DoEvents();

                i++;
                if ( i > 20 )
                {
                    break;      // exit anyway, don't way too much
                }
            }
        }

        /// <summary>
        /// Run background process
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void backWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get parameters
            BackgroundWorker worker = sender as BackgroundWorker;
            int numberOfSteps = (int)e.Argument;

            for ( int i = 0; i < numberOfSteps; i++ )
            {
                System.Threading.Thread.Sleep(1000);

                if ( worker.CancellationPending )   // test if cancelled
                {
                    e.Cancel = true;
                    break;
                }

                // Report progress and pass user data.
                // This can be used to pass only data, or only progress information,
                // or both.
                worker.ReportProgress(
                    (int)((100.0f * (float)(i+1))/ (float)numberOfSteps),
                    String.Format("Step {0}", i+1));
            }
        }

        /// <summary>
        /// Handle progress notification:
        /// extract and show progress percentage and data.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void backWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            listBox1.Items.Add(String.Format("{0}  {1}%",
                (string)e.UserState,        // user data
                e.ProgressPercentage));     // percentage
        }

        /// <summary>
        /// Background work is completed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            string s;

            if ( e.Error != null )
            {
                s = e.Error.Message;
            }
            else if ( e.Cancelled )
            {
                s = "Cancelled";
            }
            else
            {
                s = "Finished";
            }

            listBox1.Items.Add(s);
        }

    }
}

Build application and see how it works.
0
 
axsaxsCommented:
In order to avoid multithreading complexity, consider using

Application.DoEvents()

wisely. For instance, if you have a CPU intensive procedure, consider inserting a DoEvents() into it. Your UI will seem more responsive and ready.

Of course, you will deliver much better results with multithreading. But in my experience, a DoEvents well placed will solve you many problems without the multithreading complexity.

0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
VijayDixonAuthor Commented:
Thank u soo much friend

but i hav a problem

Im using visual studio 2005

if i paste this code and run the program

it says an error in the Dispose function???

wat to do??
0
 
AlexFMCommented:
This is code from VS 2005. What error exactly?
0
 
VijayDixonAuthor Commented:
ok frnd i made that work
but its just filling a list box will i be able to put other controls and will the user be able to interact with those controls when the list box is getting filled

i need to update 1500 records in the background with a thread
and while this is happening
i need to allow the user enter something in the data entry form will that be possible????
0
 
VijayDixonAuthor Commented:
what is that backWorker control that i see on the designer window????

is that an user defined control???
0
 
AlexFMCommented:
You can add other controls to the form and see that it is responsible while thread is running. For example, you can close the program when thread is running. Instead of Listbox you can use any other control, for example, progress bar.
backWorker is instance of BackgroundWorker control. You can see this control in the Toolbox, under Components tag. See also:
http://msdn2.microsoft.com/en-us/system.componentmodel.backgroundworker.aspx
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.