Solved

Events with thread

Posted on 2009-07-14
4
180 Views
Last Modified: 2012-05-07
So then I have two more questions. (sorry)

1. If I run this example I can press subscribe...the clock starts......I press unsubscribe and the clock stops. Why Aint I able to press subscribe again and it will start ticking again?

2. Is it possible to make a "start form" from where I can fire this Form1 I have now? That means I can fire up alot of diffrent Form1


Clock.CS:

______________________________

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;
 

namespace Modul3_Malmoe

{

    public class Clock

    {

        // Private Fields holding the hour, minute and second

        private int _hour;

        private int _minute;

        private int _second;

        private bool IsSubscribed;

        private bool _bSubscribe;
 
 

        // The delegate named SecondChangeHandler, which will encapsulate

        // any method that takes a clock object and a TimeInfoEventArgs

        // object as the parameter and returns no value. It's the

        // delegate the subscribers must implement.

        public delegate void SecondChangeHandler(object clock, TimeInfoEventArgs timeInformation);
 

        // The event we publish

        public event SecondChangeHandler SecondChange;
 
 

        public Clock()

        {

            _bSubscribe = true;

        }
 
 

        #region Egenskaper
 
 

        #endregion
 

        // The method which fires the Event

        protected void OnSecondChange(object clock, TimeInfoEventArgs timeInformation)

        {

            // Check if there are any Subscribers

            if (SecondChange != null)

            {

                // Call the Event

                SecondChange(clock, timeInformation);

            }

        }
 
 

        /// <summary>

        /// only changing private field _bSubscribe

        /// </summary>

        public void unsunscribe()

        {

            _bSubscribe = false;

        }
 
 
 

        // Set the clock running, it will raise an

        // event for each new second

        public void Run(System.Windows.Forms.TextBox timeTextBox)

        {

            for (; ; )

            {
 

                // Sleep 1 Second

                Thread.Sleep(1000);
 

                // Get the current time

                System.DateTime dt = System.DateTime.Now;
 

                // If the second has changed

                // notify the subscribers

                if (dt.Second != _second)

                {

                    int hours = dt.Hour;

                    string hh1 = Convert.ToString(hours / 10);

                    string hh2 = Convert.ToString(hours % 10);

                    string hh3 = hh1 + hh2;
 

                    int minute = dt.Minute;

                    string mm1 = Convert.ToString(minute / 10);

                    string mm2 = Convert.ToString(minute % 10);

                    string mm3 = mm1 + mm2;
 

                    int seconds = dt.Second;

                    string ss1 = Convert.ToString(seconds / 10);

                    string ss2 = Convert.ToString(seconds % 10);

                    string ss3 = ss1 + ss2;
 

                    // Create the TimeInfoEventArgs object

                    // to pass to the subscribers

                    TimeInfoEventArgs timeInformation = new TimeInfoEventArgs(Convert.ToInt32(hh3), Convert.ToInt32(mm3), Convert.ToInt32(ss3));
 

                    // update the state

                    _second = dt.Second;

                    _minute = dt.Minute;

                    _hour = dt.Hour;
 

                    // If anyone has subscribed, notify them

                    if (_bSubscribe) // if it is subscribed then show in textBox

                    {
 

                        OnSecondChange(this, timeInformation);

                    }
 

                    else

                        return;  // this will end your for loop
 

                }
 
 

            }
 
 

        }
 

    }
 

}
 
 
 
 

Form1.Cs

_______________________

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Threading;
 

namespace Modul3_Malmoe

{

    public partial class Form1 : Form

    {
 

        // Create a new clock

        Clock theClock;

        private bool flag = true;
 

        // Create the display

        private DisplayClock dc = new DisplayClock();
 

        // Create a Log object and tell it

        LogClock lc = new LogClock();
 
 

        public Form1()

        {

            InitializeComponent();

            theClock = new Clock();

            unsubscribeButton.Enabled = false;

            theClock.SecondChange += new Clock.SecondChangeHandler(theClock_SecondChange);
 

        }
 

        void theClock_SecondChange(object clock, TimeInfoEventArgs timeInformation)

        {

            MethodInvoker mi = delegate()

            {

                timeTextBox.Text = timeInformation.hour.ToString() + "." +

                    timeInformation.minute.ToString() + "." +

                    timeInformation.second.ToString();

                timeTextBox.Parent.Update();

            };

            updateUI(mi);

        }
 

        private void updateUI(MethodInvoker mi)

        {

            if (this.InvokeRequired)

                this.Invoke(mi);

            else

                mi();

        }
 

        private void subscribeButton_Click(object sender, EventArgs e)

        {

            subscribeButton.Enabled = false;

            unsubscribeButton.Enabled = true;
 

            // subscribe to the clock just created                

            dc.Subscribe(theClock);
 

            // to subscribe to the clock

            lc.Subscribe(theClock);
 

            // Get the clock started    
 

            MethodInvoker mi = delegate()

            {

                theClock.Run(timeTextBox);

            };

            mi.BeginInvoke(null, null);
 
 

        }
 

        private void unsubscribeButton_Click(object sender, EventArgs e)

        {

            //theClock.Subscribed = false;

            theClock.unsunscribe();

            unsubscribeButton.Enabled = false;

            subscribeButton.Enabled = true;
 
 

        }
 
 

    }

}

Open in new window

0
Comment
Question by:Mickeys
  • 2
  • 2
4 Comments
 
LVL 11

Expert Comment

by:saragani
ID: 24847373
Well, the first problem would be that Subscribe causing you to register the events buts unsubscribe
doesn't. This means that when you click on subscribe again then you will have the event registered twice.


For this we will do:
        private void unsubscribeButton_Click(object sender, EventArgs e)
        {
            theClock.unsunscribe();
            unsubscribeButton.Enabled = false;
            subscribeButton.Enabled = true;

            // unsubscribe to the clock just created                
            dc.UnSubscribe(theClock);

            // to unsubscribe to the clock
            lc.UnSubscribe(theClock);
        }


This still doesn't solve the problem that you have.


Furthermore, you are doing a loop using for but without a start or end index... so why using a for while you can use a While?




while (_bSubscribe)
            {

                // Sleep 1 Second
                Thread.Sleep(1000);

                // Get the current time
                System.DateTime dt = System.DateTime.Now;

                // If the second has changed
                // notify the subscribers
                if (dt.Second != _second)
                {
                    int hours = dt.Hour;
                    string hh1 = Convert.ToString(hours / 10);
                    string hh2 = Convert.ToString(hours % 10);
                    string hh3 = hh1 + hh2;

                    int minute = dt.Minute;
                    string mm1 = Convert.ToString(minute / 10);
                    string mm2 = Convert.ToString(minute % 10);
                    string mm3 = mm1 + mm2;

                    int seconds = dt.Second;
                    string ss1 = Convert.ToString(seconds / 10);
                    string ss2 = Convert.ToString(seconds % 10);
                    string ss3 = ss1 + ss2;

                    // Create the TimeInfoEventArgs object
                    // to pass to the subscribers
                    TimeInfoEventArgs timeInformation = new TimeInfoEventArgs(Convert.ToInt32(hh3), Convert.ToInt32(mm3), Convert.ToInt32(ss3));

                    // update the state
                    _second = dt.Second;
                    _minute = dt.Minute;
                    _hour = dt.Hour;

                    // If anyone has subscribed, notify them
                    if (_bSubscribe) // if it is subscribed then show in textBox
                    {

                        OnSecondChange(this, timeInformation);
                    }
                }
            }



The reason why the loop doesn't restart is because bSubscribe is false. You set it to tru when you create the clock object, and set it to false when you unsubscribe.
But you don't set it to true again.



So we will change the Run Function (Since it acts like a subscrube):



public void Run()
        {
            _bSubscribe = true;
            while (_bSubscribe)
            {

                // Sleep 1 Second
                Thread.Sleep(1000);

                // Get the current time
                System.DateTime dt = System.DateTime.Now;

                // If the second has changed
                // notify the subscribers
                if (dt.Second != _second)
                {
                    int hours = dt.Hour;
                    string hh1 = Convert.ToString(hours / 10);
                    string hh2 = Convert.ToString(hours % 10);
                    string hh3 = hh1 + hh2;

                    int minute = dt.Minute;
                    string mm1 = Convert.ToString(minute / 10);
                    string mm2 = Convert.ToString(minute % 10);
                    string mm3 = mm1 + mm2;

                    int seconds = dt.Second;
                    string ss1 = Convert.ToString(seconds / 10);
                    string ss2 = Convert.ToString(seconds % 10);
                    string ss3 = ss1 + ss2;

                    // Create the TimeInfoEventArgs object
                    // to pass to the subscribers
                    TimeInfoEventArgs timeInformation = new TimeInfoEventArgs(Convert.ToInt32(hh3), Convert.ToInt32(mm3), Convert.ToInt32(ss3));

                    // update the state
                    _second = dt.Second;
                    _minute = dt.Minute;
                    _hour = dt.Hour;

                    // If anyone has subscribed, notify them
                    if (_bSubscribe) // if it is subscribed then show in textBox
                    {

                        OnSecondChange(this, timeInformation);
                    }
                }
            }
        }


I've removed the Textbox from the arguments of the Run since we don't need it anymore and I've also put a _bSubscribe = true before the loop starts.

This answers Q1.



Q2, yes.
each form will have it's own clock objects so you can have multiple forms.
0
 

Author Comment

by:Mickeys
ID: 24847445
This is great now I start to understand.

So lets say I have done a startup form with a button called START

How can I then fire up multiplie FORM1?

I mean if I press once I want to start one FORM1. If I press again a new one starts.

Is it
Form1 myform = new Form1()

and then????
0
 
LVL 11

Accepted Solution

by:
saragani earned 500 total points
ID: 24847560
Ok, I was away. I just saw your question

add a new form: Form2
go to program.cs and change it so it will run Form2 instead of Form1

on Form2 add a button and have the following code in the click event:

Form1 myform = new Form1();
myform.Show();
0
 

Author Closing Comment

by:Mickeys
ID: 31603173
Thx for everything.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

757 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now