Solved

MULTITHREADED WINDOWS APPLICATION IN C#

Posted on 2006-11-05
8
858 Views
Last Modified: 2012-05-05
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??????
0
Comment
Question by:VijayDixon
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 17876536
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 125 total points
ID: 17876545
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
 

Expert Comment

by:axsaxs
ID: 17881272
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:VijayDixon
ID: 17888417
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 17888422
This is code from VS 2005. What error exactly?
0
 
LVL 1

Author Comment

by:VijayDixon
ID: 17888585
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
 
LVL 1

Author Comment

by:VijayDixon
ID: 17888597
what is that backWorker control that i see on the designer window????

is that an user defined control???
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17888669
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question