Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm General / April 2005

Tip: Looking for answers? Try searching our database.

Object passed to TimerHandler immutable?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Bill - 10 Apr 2005 03:47 GMT
This one has me stumped.  I'm using sample code in the C# Programmer's
Cookbook as a guide.  Specifially, Recipe 4.3, Execute a Method Using a
Timer.

I created a form with a ProgressBar on it (Min=0, Max=100).  When I
created my Timer object I passed the ProgressBar as the second
parameter, the "state" object.  This object is passed to the
TimerHandler.

Inside the TimerHandler I increment ProgressBar.Value by 1 unless its
at the Max value, in which case I reset it to the Min value.\

I expected to see the ProgressBar grow in the form, but nothing
happened.

I set a few breakpoints and discovered that indeed the ProgressBar
object is being passed through the Timer object to the TimerHandler
method.  However, in the TimerHandler the ProgressBar object is always
in its initial state.

This leads me to believe I'm getting a COPY of the ProgressBar object
in my TimerHandler.

As an experiment I left the Timer object out of the loop and called
TimerHandler directly from a loop and it worked perfectly.

I'm guessing my "problem" is rooted in the fact that I'm trying to
modify an object across threads.

Does anyone have any ideas what I'm doing wrong or how I might
accomplish my goal?

Thanks,

Bill...
Bill - 10 Apr 2005 05:38 GMT
OK, so I did a bit more searching and discovered that this question
gets asked about once a week.  Apparently it was my turn to ask it this
week.  ;-)

I neglected to mention in my original post that this all all under .NET
Compact Framework.

Anyway... I figured it all out and now have a nice progress bar
crawling across my display while my worker thread is doing its thing.

For those who may be interested, here's a piece of sample code:

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Diagnostics;

namespace Thread_Timer_Callback_Test
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.ProgressBar pbProgress;
        private System.Windows.Forms.Label lblMsg;
        private System.Windows.Forms.MainMenu mainMenu1;
        private System.Windows.Forms.MenuItem menuItem1;
        private TimerCallback handler;
        private delegate void pbUpdateDelegate(Object sender, EventArgs e);
        private System.Threading.Timer timer;
        private System.Windows.Forms.Button btnClickMe;
        private System.Windows.Forms.Button btnStop;
        private System.Windows.Forms.Button btnRestart;
        private int i = 0;

        public Form1()
        {
            InitializeComponent();
            handler = new TimerCallback(TimerHandler);
        }
        protected override void Dispose( bool disposing )
        {
            base.Dispose( disposing );
        }
        private void InitializeComponent()
        {
            this.mainMenu1 = new System.Windows.Forms.MainMenu();
            this.pbProgress = new System.Windows.Forms.ProgressBar();
            this.lblMsg = new System.Windows.Forms.Label();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.btnClickMe = new System.Windows.Forms.Button();
            this.btnStop = new System.Windows.Forms.Button();
            this.btnRestart = new System.Windows.Forms.Button();
            this.mainMenu1.MenuItems.Add(this.menuItem1);
            this.pbProgress.Location = new System.Drawing.Point(8, 56);
            this.pbProgress.Size = new System.Drawing.Size(224, 20);
            this.lblMsg.Location = new System.Drawing.Point(8, 24);
            this.lblMsg.Size = new System.Drawing.Size(224, 20);
            this.lblMsg.Text = "Message appears here";
            this.lblMsg.TextAlign = System.Drawing.ContentAlignment.TopCenter;
            this.menuItem1.Text = "Exit";
            this.menuItem1.Click += new
System.EventHandler(this.menuItem1_Click);
            this.btnClickMe.Location = new System.Drawing.Point(84, 96);
            this.btnClickMe.Text = "Click Me";
            this.btnClickMe.Click += new
System.EventHandler(this.btnClickMe_Click);
            this.btnStop.Location = new System.Drawing.Point(84, 136);
            this.btnStop.Text = "Stop";
            this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
            this.btnRestart.Location = new System.Drawing.Point(84, 176);
            this.btnRestart.Text = "Restart";
            this.btnRestart.Click += new
System.EventHandler(this.btnRestart_Click);
            this.Controls.Add(this.btnRestart);
            this.Controls.Add(this.btnStop);
            this.Controls.Add(this.btnClickMe);
            this.Controls.Add(this.lblMsg);
            this.Controls.Add(this.pbProgress);
            this.Menu = this.mainMenu1;
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
        }
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            timer = new System.Threading.Timer(handler, this.pbProgress, 0,
100);
        }

        private void TimerHandler(object obj)
        {
            pbUpdateDelegate _pbUpdate = new pbUpdateDelegate(pbUpdate);
            ((ProgressBar)obj).Invoke(new EventHandler(_pbUpdate));
        }

        private void pbUpdate(Object sender, EventArgs e)
        {
            if (this.pbProgress.Value == this.pbProgress.Maximum)
                this.pbProgress.Value = this.pbProgress.Minimum;
            else
                this.pbProgress.Value++;
        }

        private void menuItem1_Click(object sender, System.EventArgs e)
        {
            timer.Dispose();
            Application.Exit();
        }

        private void btnClickMe_Click(object sender, System.EventArgs e)
        {
            i++;
            this.lblMsg.Text = "That was click #" + i.ToString();
        }

        private void btnStop_Click(object sender, System.EventArgs e)
        {
            timer.Change(0,0);
        }

        private void btnRestart_Click(object sender, System.EventArgs e)
        {
            timer.Change(0,100);
        }
    }
}
Mehdi - 10 Apr 2005 12:46 GMT
> OK, so I did a bit more searching and discovered that this question
> gets asked about once a week.  Apparently it was my turn to ask it this
[quoted text clipped - 5 lines]
> Anyway... I figured it all out and now have a nice progress bar
> crawling across my display while my worker thread is doing its thing.

Something looks just strange in your code. Why are you using a
System.Threadind.Timer since at each timer tick you are marshalling the
call to your pbUpdate function to the UI thread? In this case, a simple
System.Window.Form.Timer timer would make more sense since its callback
method executes in the UI thread already and not in a worker thread, that
would make the code simpler.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.