Threading.Timer fires many times??

W

whtinkm

Hi, All
Recently, my project need some code like following:

using System;
using System.Threading;

namespace MyTimerTest
{
class Class1
{
protected System.Threading.Timer guarder;
private string testFlag="";

public void Init()
{
System.Console.WriteLine("Begin Test.....");
guarder=new Timer(new
TimerCallback(CheckCurrentState),null,5000,100);
}

public void Destroy()
{
//Dispose timer
}
protected void CheckCurrentState(object state)
{
string
strTemp=System.Threading.Thread.CurrentThread.GetHashCode().ToString();


try
{
if(testFlag!="" && testFlag!=strTemp)
{
System.Console.WriteLine("Fatal error1: "+testFlag+","+strTemp);
}

testFlag=strTemp;

guarder.Change(Timeout.Infinite,0); //disable the timer

System.Threading.Thread.Sleep(300);
}
catch(Exception ex)
{
System.Console.WriteLine("CheckCurrentState: "+ex.Message);
}
finally
{
if(testFlag!=strTemp)
{
System.Console.WriteLine("Fatal error2: "+testFlag+","+strTemp);
}
testFlag="";

guarder.Change(100,100); //enable timer again
}
}

[STAThread]
static void Main(string[] args)
{
Class1 dd=new Class1();

dd.Init();

System.Console.ReadLine();

dd.Destroy();
}
}
}

I confused that when I run the simple test code for a moment, i will
get the following output
Fatal error1: 1,2
Fatal error2 ,2
......

I think when it enters the event process it has disable the timer using

Change(Timeout.Infinite,0)

According to the output, the timer fires multi-times, why?

Thanks for any ideas
Harry
 
K

Kevin Spencer

g> I think when it enters the event process it has disable the timer using
Change(Timeout.Infinite,0)

According to the output, the timer fires multi-times, why?

guarder.Change(100,100); //enable timer again

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A watched clock never boils.

Hi, All
Recently, my project need some code like following:

using System;
using System.Threading;

namespace MyTimerTest
{
class Class1
{
protected System.Threading.Timer guarder;
private string testFlag="";

public void Init()
{
System.Console.WriteLine("Begin Test.....");
guarder=new Timer(new
TimerCallback(CheckCurrentState),null,5000,100);
}

public void Destroy()
{
//Dispose timer
}
protected void CheckCurrentState(object state)
{
string
strTemp=System.Threading.Thread.CurrentThread.GetHashCode().ToString();


try
{
if(testFlag!="" && testFlag!=strTemp)
{
System.Console.WriteLine("Fatal error1: "+testFlag+","+strTemp);
}

testFlag=strTemp;

guarder.Change(Timeout.Infinite,0); //disable the timer

System.Threading.Thread.Sleep(300);
}
catch(Exception ex)
{
System.Console.WriteLine("CheckCurrentState: "+ex.Message);
}
finally
{
if(testFlag!=strTemp)
{
System.Console.WriteLine("Fatal error2: "+testFlag+","+strTemp);
}
testFlag="";

guarder.Change(100,100); //enable timer again
}
}

[STAThread]
static void Main(string[] args)
{
Class1 dd=new Class1();

dd.Init();

System.Console.ReadLine();

dd.Destroy();
}
}
}

I confused that when I run the simple test code for a moment, i will
get the following output
Fatal error1: 1,2
Fatal error2 ,2
.....

I think when it enters the event process it has disable the timer using

Change(Timeout.Infinite,0)

According to the output, the timer fires multi-times, why?

Thanks for any ideas
Harry
 
W

whtinkm

Thanks Kevin
but would you mind giving me more detailed tips, i do not understand
what your said completely :)

regards
Harry
 
J

jeremiah johnson

Thanks Kevin
but would you mind giving me more detailed tips, i do not understand
what your said completely :)

regards
Harry

What he said was, that the timer is firing many times because you turn
the timer on again with the line of code that he pointed out.

try removing that line of code so that the timer only executes once.
 
W

whtinkm

Hi jeremiah
Maybe i did not describe my problem clearly :)
I want to execute some tasks repeatedly
There should be some interval between two executions.
If one execution consumes too many time, Threading.Timer will use a new
thread to execute
callback function before previous execution completed, it result in
multi-threads execute these tasks at the same time
but i want to just only one thread do it, so before one execution begin
i disable
the Timer, and after it completed, i enable the timer again.
Yes, i can use other ways to avoid the problem, but i want to know why
my test code failed?

wish to your reply :)

regards
Harry
 
C

Chris Dunaway

guarder=new Timer(new
TimerCallback(CheckCurrentState),null,5000,100);

Unless I have mis-understood how the timer works, your statement means:


"After 5000ms has passed, call the CheckCurrentState callback and then
call it every 100ms thereafter".

Is that your intent? To call CheckCurrentState after 5 seconds and
then every 10th of a second thereafter? Or do you want it called every
5 seconds? To do that you would use guarder = new Timer(new
TimerCallback(CheckCurrentState), null, 5000, 5000);

Perhaps, because the timers interval is 100ms, that it is being called
more than once before it is disabled? What if you moved the line to
disable the timer to the top of the callback method so it gets disabled
as soon as possible?
 
W

whtinkm

Chris Dunaway 写é“:
Unless I have mis-understood how the timer works, your statement means:


"After 5000ms has passed, call the CheckCurrentState callback and then
call it every 100ms thereafter".

Is that your intent? To call CheckCurrentState after 5 seconds and
then every 10th of a second thereafter? Or do you want it called every
5 seconds? To do that you would use guarder = new Timer(new
TimerCallback(CheckCurrentState), null, 5000, 5000);

Perhaps, because the timers interval is 100ms, that it is being called
more than once before it is disabled? What if you moved the line to
disable the timer to the top of the callback method so it gets disabled
as soon as possible?

Thanks Chris
i do not understand why the disable operation will consume more than
100ms? The GC is working?

regards
Harry
 
Top