Timer Array in c#, VS2005

  • Thread starter Thread starter Gina_Marano
  • Start date Start date
G

Gina_Marano

I have created an array of timers (1-n). At first I just created
windows form timers but I read that system timers are better for
background work. The timers will just be monitoring different
directories and updating a database. No interaction with the GUI.

Problem is that the system timers do not have a tag property so I can
tie in an object.

example (old way):

public class TimerInfo
{
public string sPath;
public int iInterval;
}

private ArrayList arrTimers = new ArrayList();

private void CreateTimers(int NUMBER_TIMERS)
{
TimerInfo Info;
System.Timers.Timer newTimer;

for (int i = 1; i <= NUMBER_TIMERS; i++)
{
Info = new TimerInfo();
Info.sPath = "c:\\";
Info.iInterval = 60000;

newTimer = new System.Timers.Timer();
newTimer.Elapsed += timerWatch_Tick;
newTimer.Interval = 20000;
newTimer.Tag = TimerInfo;
newTimer.Enabled = true;

arrTimers.Add(newTimer);
}
}

private void timerWatch_Tick(object sender, EventArgs e)
{
string sPath = ((TimerInfo)((Timer)sender).Tag).sPath;
CheckForFile(sPath);
}


Do I need to call Dispose if I want to reset the timer array?

foreach (System.Timers.Timer atimer in arrTimers)
{
atimer.Dispose();
}
arrTimers.Clear();

Thanks for your help. I am struggling as a newbie through C# even
though it is a really neat language.

~Gina~
 
There are directory watchers just for this purpose. You can tell it to
watch certain files, wildcards, and directories. You then get callbacks
when something happens.

Lookup File System Watcher in your help.
 
I have had nothing except bad luck with those directory watchers. One
reason that might be the reason is that I am watching network
directories and I doubt I will catch those events.

thanks though

~Gina~
 
I better clearly state my main question (besides maybe a code review)
is:

Is there a trick so I can assign an object to a system timer since it
does not have a tag field?

example (old way using form timer) but I need to

public class TimerInfo
{
public string sPath;
public int iInterval;
}

private ArrayList arrTimers = new ArrayList();

private void CreateTimers(int NUMBER_TIMERS)
{
TimerInfo Info;
Timer newTimer;

for (int i = 1; i <= NUMBER_TIMERS; i++)
{
Info = new TimerInfo();
Info.sPath = "c:\\";
Info.iInterval = 60000;

newTimer = Timers.Timer();
newTimer.Tick += timerWatch_Tick;
newTimer.Interval = 20000;
newTimer.Tag = TimerInfo; //<-- this does not exist for the
system timer
newTimer.Enabled = true;

arrTimers.Add(newTimer);
}
}

private void timerWatch_Tick(object sender, EventArgs e)
{
(TimerInfo)((Timer)sender).Enabled = false;
try
{
string sPath = ((TimerInfo)((Timer)sender).Tag).sPath;
CheckForFile(sPath);
}
finally
{
(TimerInfo)((Timer)sender).Enabled = true;
}
}

~Gina~
 
Are you saying you want a timer object that does not have a tag info? Or a
object that has everything a timer has and also has a tag object?
 
Hi Daniel:

I currently have an arraylist of System.Timers.Timer Timers.

The System.Timers.Timer Timers do not have a Tag property.I use the tag
property of the Timer to store an object so that on the tick/elapse
event I can get timer specific settings.

I am open to any ideas. I read that System.Timers.Timer Timers are the
timers to use since it does not interact with the GUI at all.

Please ask as many questions as you wish. I am new to C# and probably
don't always use the correct terminology.

~Gina~
 
Hi Gina

"The System.Timers.Timer Timers do not have a Tag property"

Yes they do have a tag property, i just checked and a timer has the tag.

I get what yiu are doing as i do something similar in my app. You have a
load of timers in an array and you want to know when a particular timer has
finished or its time has elapsed?

As i said they do have a tag property so i am confused about you saying that
or why you dont think they have one?

In my situation i did this:

Make a TimerManager class
Make a MyTimer class (or some better app specific name)

Now in your MyTimer class do this

class MyTimer : Timer //and inherit from timer

Now you can add any attributes you like to your timer and it will have all
the functionality of the normal timer.

so if you have an enumerator such as (just using examples of timer
categories)

enum TimerType : int
{
LunchBreak,
ClassLength
}

You could then do this in MyTimer class

class MyTimer : Timer
{
TimerType _myTimerType;

public event timerElapsed;
public delegate timerElapsed TimeElapsed(TimerType t);

MyTimer(TimerType t)
{
_myTimerType = t;
Elapsed += OnTimerElapsed; //.net 2 syntax
}

public TimerType
{
get{return _myTimerType; }
}

public void OnTimerElapsed( object sender,
System.Timers.ElapsedEventArgs e)
{
timerElapsed(_myTimerType);
}

}


Then in your TimerManager class do this

class TimerManager
{
private ArrayList MyTimerList;
TimerManager(){};

//create timers
public void CreateTimer(TimerType t, int interval);
{
MyTimer m = new MyTimer(t);
m.Interval = interval;
m.timerElapsed += TimerComplete;
MyTimerList.Add(m);
}

public void TimerComplete(TimerType t)
{
switch(t)
{
case LunchBreak:
//do something
break;

case ClassLength:
//do something
break;
}
}

}


I have written that off the top of my head so i dont know if it will compile
but i hope it gives you an idea of one implementation method? By doing that
you wrap up the timer to have functionality you need and only ever need the
TimerManager. So to create a timer from some outside class:

TimerManager tm = new TimerManager();
tm.CreateTimer(TimerType.LunchBreak);

Of course you need to add methods to the timer manager class for starting
the timers, or have them start the moment they are created and similarly the
same for stopping them, just a foreach to iterate through the array would do
it.

So the idea is the enumerator makes each timer you create unique. You can
easily adjust to pass more data from the MyTimer into the TimerComplete and
this allows a central manegemt of all the timers. So the TimerComplete in
the case above will fire everytime any timer elapsed its interval and then
it checks which timer it was and you can react as you see fit.

Thats the way i did what i think you are trying to do. Does that help at
all?
 
Hi Daniel:

I really appreciate the effort of your response. It looks like it will
give me what I want which is the ability to assign each individual
timer a path or other properties that the timer will reference on its
elapse event.

As for the tag property. I think you may be refering to a different
timer that I am referring to. there is a windows.form.timer (or
something close) and a System.Timers.Timer which is used for services
or in my case, a form without the need for the timer to interact with
the GUI.

http://www.informit.com/guides/content.asp?g=dotnet&seqNum=200&rl=1
(The site seems really slow today, you may need to keep refreshing
until the article actually pops up)

System.Timers.Timer:

Public Constructors
Timer
Public Properties
AutoReset
Container
Enabled
Interval
Site
SynchronizingObject
Protected Properties
CanRaiseEvents
DesignMode
Events
Public Methods
BeginInit
Close
CreateObjRef
Dispose
EndInit
Equals
GetHashCode
GetLifetimeService
GetType
ReferenceEquals
Start
Stop
ToString

But what I gave me may be what I wanted anyway. Using the tag was a
hack to get what I wanted.

~Gina~
 
But you can pass a state object to the constructor that gets passed to the
callback to get the same effect - no?

--
William Stacey [C# MVP]

| Hi Daniel:
|
| I really appreciate the effort of your response. It looks like it will
| give me what I want which is the ability to assign each individual
| timer a path or other properties that the timer will reference on its
| elapse event.
|
| As for the tag property. I think you may be refering to a different
| timer that I am referring to. there is a windows.form.timer (or
| something close) and a System.Timers.Timer which is used for services
| or in my case, a form without the need for the timer to interact with
| the GUI.
|
| http://www.informit.com/guides/content.asp?g=dotnet&seqNum=200&rl=1
| (The site seems really slow today, you may need to keep refreshing
| until the article actually pops up)
|
| System.Timers.Timer:
|
| Public Constructors
| Timer
| Public Properties
| AutoReset
| Container
| Enabled
| Interval
| Site
| SynchronizingObject
| Protected Properties
| CanRaiseEvents
| DesignMode
| Events
| Public Methods
| BeginInit
| Close
| CreateObjRef
| Dispose
| EndInit
| Equals
| GetHashCode
| GetLifetimeService
| GetType
| ReferenceEquals
| Start
| Stop
| ToString
|
| But what I gave me may be what I wanted anyway. Using the tag was a
| hack to get what I wanted.
|
| ~Gina~
|
 
As an alternative you could derive from the timer class as below. That
way you can add any additional information you require.

public class Class1 : System.Timers.Timer
{
string _name;

public Class1(string pName)
{
_name = pName;
}
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
}
 
private void button24_Click(object sender, EventArgs e)
{
Console.WriteLine("Running a job every 5 seconds.");
string s = "MyObject";
System.Threading.Timer timer = null;
timer = new System.Threading.Timer(
delegate(object state)
{
string s1 = (string)state;
timer.Change(5000, -1);
Console.WriteLine("Job ran at: {0} State:{1}",
DateTime.Now, s1);
}, s, 5000, -1);
}

As others have said, you can derive from Timer also to add your state
member(s).

--
William Stacey [C# MVP]

| Hi William:
|
| Can you give me a short example. I am a C# and thread newbie.
|
| ~Gina~
|
| William Stacey [C# MVP] wrote:
| > But you can pass a state object to the constructor that gets passed to
the
| > callback to get the same effect - no?
| >
| > --
| > William Stacey [C# MVP]
|
 
Back
Top