System.Timers.Timer() sometimes gets stuck and disappears??

G

Guest

Hello,

Wow...I have one for you all and hopefully I am not understanding this timer
object correctly. I have a timer setup that pulses a connection through a
socket every 60 seconds. But it seems recently connections just drop off
because the timer stops firing.

My question is if there is a timeout in the timer event that just shuts down
the call if the timer event is taking too long to complete...?

It seems that it almost looks when reading log files that something either
locks up inthe timer event and never retruns (very unlikely since it happens
at different places in the event), or the event just stops running in the
middle of something although the user application never reports any error
boxes to the user and they continue to use it for hours.

Here is some code if it helps you all out:

// in constructor
this.HeartBeatTimer = new System.Timers.Timer();
this.HeartBeatTimer.Interval = 1 * 60 * 1000; // every
1 minute
this.HeartBeatTimer.Elapsed += new
System.Timers.ElapsedEventHandler(DoHeartBeat); // send heartbeat

// later in code they log in and...
this.HeartBeatTimer.Enabled = true;

{At this point everything works fine for a long time.}

// my event handler
public void DoHeartBeat(object sender, EventArgs eArgs)
{
LogStuff.LogData("$$ FIRED Heartbeat --> just set enabled to false"); // ttt

// Shut down the timer until we are done sending the heartbeat
HeartBeatTimer.Enabled = false;

if(blah...)
{
LogStuff.LogData("$$ A"); // ttt

try
{
// query an activeX control to check statuses
...
LogStuff.LogData("$$ B"); // ttt

// send Heart Beat
String recData = mySocketClient.Send(....);

LogStuff.LogData("$$ C"); // ttt

}
catch(...)
{
// logging my error here
}

} // end IF

LogStuff.LogData("$$ Done firing heartbeat --> Enabled HB again.");

// Start the timer back up again when we are done
HeartBeatTimer.Enabled = true;

return;

} // end DoHeartBeat ()

Thats it. Nowhere in there do I have a return except at the very end. It
should never exit before it gets to the return. It never throws an error
either since nothing is ever logged at that spot (except other circumstances
when other things go wrong).

Sometimes when I read the log file I will see:
$$ FIRED Heartbeat --> just set enabled to false
$$ A
.... and thats it, Nothing from this timer ever again until program restarts.

Sometimes I will see:
$$ FIRED Heartbeat --> just set enabled to false
$$ A
$$ B
.... and thats it, Nothing from this timer ever again until program restarts.

I cannot reproduce this locally. It seems this happens after hours of use
on our customers computers.

Please, can anyone help us understand these timers any better?

Thank you all very much for reading this. Hope someone can help.

Rob K
 
S

Steven Nagy

Whats the thread count after it starts failing?
I could be misunderstanding the class, but to my knowledge, the
System.Timers.Timer class is designed to 'Elapse' only once. This event
occurs in a different thread. By setting it enabled again, the next
'Elapsed' will probably occur in another thread, with the current
thread potentially not closing properly. I think there is a max thread
pool count so possibly this is happening? Just a stab in the dark. I
could be (most likely) totally wrong.
 
W

Willy Denoyette [MVP]

| Hello,
|
| Wow...I have one for you all and hopefully I am not understanding this
timer
| object correctly. I have a timer setup that pulses a connection through a
| socket every 60 seconds. But it seems recently connections just drop off
| because the timer stops firing.
|
| My question is if there is a timeout in the timer event that just shuts
down
| the call if the timer event is taking too long to complete...?
|
| It seems that it almost looks when reading log files that something either
| locks up inthe timer event and never retruns (very unlikely since it
happens
| at different places in the event), or the event just stops running in the
| middle of something although the user application never reports any error
| boxes to the user and they continue to use it for hours.
|
| Here is some code if it helps you all out:
|
| // in constructor
| this.HeartBeatTimer = new System.Timers.Timer();
| this.HeartBeatTimer.Interval = 1 * 60 * 1000; //
every
| 1 minute
| this.HeartBeatTimer.Elapsed += new
| System.Timers.ElapsedEventHandler(DoHeartBeat); // send heartbeat
|
| // later in code they log in and...
| this.HeartBeatTimer.Enabled = true;
|
| {At this point everything works fine for a long time.}
|
| // my event handler
| public void DoHeartBeat(object sender, EventArgs eArgs)
| {
| LogStuff.LogData("$$ FIRED Heartbeat --> just set enabled to false"); //
ttt
|
| // Shut down the timer until we are done sending the heartbeat
| HeartBeatTimer.Enabled = false;
|
| if(blah...)
| {
| LogStuff.LogData("$$ A"); // ttt
|
| try
| {
| // query an activeX control to check statuses
| ...
| LogStuff.LogData("$$ B"); // ttt
|
| // send Heart Beat
| String recData = mySocketClient.Send(....);
|
| LogStuff.LogData("$$ C"); // ttt
|
| }
| catch(...)
| {
| // logging my error here
| }
|
| } // end IF
|
| LogStuff.LogData("$$ Done firing heartbeat --> Enabled HB again.");
|
| // Start the timer back up again when we are done
| HeartBeatTimer.Enabled = true;
|
| return;
|
| } // end DoHeartBeat ()
|
| Thats it. Nowhere in there do I have a return except at the very end. It
| should never exit before it gets to the return. It never throws an
error
| either since nothing is ever logged at that spot (except other
circumstances
| when other things go wrong).
|
| Sometimes when I read the log file I will see:
| $$ FIRED Heartbeat --> just set enabled to false
| $$ A
| ... and thats it, Nothing from this timer ever again until program
restarts.
|
| Sometimes I will see:
| $$ FIRED Heartbeat --> just set enabled to false
| $$ A
| $$ B
| ... and thats it, Nothing from this timer ever again until program
restarts.
|
| I cannot reproduce this locally. It seems this happens after hours of use
| on our customers computers.
|
| Please, can anyone help us understand these timers any better?
|
| Thank you all very much for reading this. Hope someone can help.
|
| Rob K
|

This is not a timer issue, the timer no longer fires because your code get's
blocked somewhere after you disabled the HeartBeatTimer timer but BEFORE you
enable it again.
It's impossible to tell what's going on whithout you showing more code, but
what's important is the ActiveX control...
Is this a real control? I mean a native ActiveX control (OC96) windowed or
window-less, then you have a design issue, AX controls must (and will) run
in a STA thread, timer eventhandlers run on a threadpool thread (which are
MTA threads). That means that your control will be hosted on an STA thread
(the calls will be marshaled from MTA to STA by COM), the problem is - which
thread? To answer this question I need to know What kind of application this
is.

Willy.
 
G

Guest

Hello Steven,

Thank you for replying. As you probably guessed, I have been playing with
this all day... and no success.

I entered these lines of code into my project to check number of threads
available (I don't know how to check how many are actually used):

int workerThreadsAvail = 0, otherThreadsAvail = 0; // ttt
System.Threading.ThreadPool.GetAvailableThreads(out
workerThreadsAvail, out otherThreadsAvail); // ttt

LogStuff.LogData("$$ FIRED Heartbeat --> just set enabled to
false, #threads avail: " + workerThreadsAvail.ToString() + " -> " +
otherThreadsAvail.ToString()); // ttt

This fluctuates between 49 and 48 consistently
$$ FIRED Heartbeat --> just set enabled to false, #threads avail: 49 -> 1000
or sometimes
$$ FIRED Heartbeat --> just set enabled to false, #threads avail: 48 -> 1000
but then goes back to 49.

However, in my painful troubleshooting session this morning, I as able to
narrow down where the problem is comming from. I think there is 2 different
problems. 1 with the activeX control, and the other with the communications
object. I think we fixed the communications one, but the activeX object is
another story.

My question is if you may know if there is a timeout I can do in this
heartbeat function that will either timeout this current thread (timer call)
or a way to timeout directly in the line of code that is executing the
activeX property call...?

Is this even possible? I have been researching the net and cannot find
anything so far.

Thanks again for your help! We really appreciate it here!

Rob K
 
G

Guest

I agree Willy. Thank you for responding. As I was explaining to Steve
above, I think that this is getting stuck at the activeX control.
Unfortunately, I am unable to say which activeX control I am using because of
all this confidentiality red tape (*sigh).

But what I can say is that this control was made by a 3rd party (that I am
growing to really despise). It appears it never returns from its call. At
this point in the HB function:

// query an activeX control to check statuses
int myValue = activeXControl1.getMyValue();

This is where it blocks (as you suspected). So... upon thinking about this
more, is there a way in .NET 2.0 C# to cause this call to timeout? If I
could timeout the entire DoHeartBeat function or just timeout this single
call in-line, it would be wonderful! I checked the net and cannot find
anything so far that allows this.

I was also was pondering the threading stuff you were talking about. So I
made sure that I called the activeX control through the main thread that it
was called on my changing my code from:

int myValue = activeXControl1.getMyValue();

to

int myValue = 0;
activeXControl1.Invoke((System.Windows.Forms.MethodInvoker)delegate
{
myValue = activeXControl1.getMyValue();
});
// now I have myValue!!! :)

Hopefully this means it is executing this on the main thread. I tested and
ran this and for a while thought this was the solution... but then it locked
in this thread again.

Any ideas on a timeout?

Thanks so much. All of us here value your input and responses.

Thanks!

Rob K
 
G

Guest

Willy, I forgot to answer your last question. Although I am relatively new
to the C# language (about 1 year now), I think it is running in STA mode. In
the program.cs is says [STAThread]. But I call threads all the time
throughout the program to do little operations to keep the GUI thread free.

Hope this further helps. I could be doing stuff totally wrong though... not
sure since I am the first person here at our company to program in C#...
there is no one here to ask help from. :-(

Thanks Willy!

Rob K
 
W

Willy Denoyette [MVP]

Rob, see inline.

Willy.

|I agree Willy. Thank you for responding. As I was explaining to Steve
| above, I think that this is getting stuck at the activeX control.
| Unfortunately, I am unable to say which activeX control I am using because
of
| all this confidentiality red tape (*sigh).
|
| But what I can say is that this control was made by a 3rd party (that I am
| growing to really despise). It appears it never returns from its call.
At
| this point in the HB function:
|
| // query an activeX control to check statuses
| int myValue = activeXControl1.getMyValue();
|
| This is where it blocks (as you suspected). So... upon thinking about
this
| more, is there a way in .NET 2.0 C# to cause this call to timeout? If I
| could timeout the entire DoHeartBeat function or just timeout this single
| call in-line, it would be wonderful! I checked the net and cannot find
| anything so far that allows this.
|
| I was also was pondering the threading stuff you were talking about. So
I
| made sure that I called the activeX control through the main thread that
it
| was called on my changing my code from:
|
| int myValue = activeXControl1.getMyValue();
|
| to
|
| int myValue = 0;
| activeXControl1.Invoke((System.Windows.Forms.MethodInvoker)delegate
| {
| myValue = activeXControl1.getMyValue();
| });
| // now I have myValue!!! :)
|

Ok good move, now you are effectively delegating the call,
Now you should not call Invoke on the AX instance reference, you should use
a Forms control instance (say the Form itself). Another thing you should
look at is the point of declaration/definition of activeXControl1, this
variable (guess it's a static) should be initialize/assigned on the UI (STA)
thread. If it's assigned on another thread, the variable will hold a proxy
instead of a direct reference. And to make sure we are dealing with a real
AX control (I'm confident it is), you could check the registration of the
control, watch the "ThreadingModel" in the registry (it should be Apartment)
or use OleView to check this out.



| Hopefully this means it is executing this on the main thread. I tested
and
| ran this and for a while thought this was the solution... but then it
locked
| in this thread again.
|
| Any ideas on a timeout?
|
No, if the call is a non returning COM call it's just like another blocking
function call, if the function blocks (or enters en endless loop), nothing
can stop it other than destroying the thread it runs on. Note that I'm not
sure it's the call who blocks in native code, it's also possible that the
call doesn't get dispatched to the object code (of the COM object) because
of marshaling issues, that's why it's important to understand what I said
above.
To summarize, an AX instance must live on an pumping STA thread (like the
UI), and calls should be direct calls, not marshaled using a COM proxy
(cross apartment/thread).



Willy.
 
G

Guest

Willy,

Thank you so much for your help. You were right. The activeX was blocking
the call. Although I still unsure why, I devised a solution. We called it
with a timeout function. Basically, we used this code found here:

http://weblogs.asp.net/israelio/archive/2004/06/19/159985.aspx

But modified it so that there was no classes and I could fit in inline.
Then I called my code like this:

.... in the timer event handler:
bool success = StartWithTimeout(DoHeartBeatStuff, 60);

.... here is my hb function:
private void DoHeartBeatStuff()
{
.....
// the call to the acitveX control
}


..... then here is my timeout function:
private bool StartWithTimeout(RunThisFunctionDelegateTimeout
whichFunctionToRun, int timeoutSeconds)
{
System.Threading.Thread th = new System.Threading.Thread(new
System.Threading.ParameterizedThreadStart(DoTimeoutFunctionStart));

// Sets the state of the specified event to non-signaled.
evnt.Reset();

// start thread
th.Start((object)whichFunctionToRun);

// wait with timeout on the event
if (evnt.WaitOne(TimeSpan.FromSeconds(timeoutSeconds), false))
{
// Sucess - timeout did not occurred
return true;
}
else
{
LogStuff.LogError("[256] Function Timed out! Aborting
call...");

// Failure - Timeout - do cleanup
try
{
th.Abort();
}
catch (Exception exec)
{
LogStuff.LogError("[257] Could not abort timed out
function! Details: " + exec.Message);
}

return false;
}
} // end StartWithTimeout ()

.... and later:

public void DoTimeoutFunctionStart(object whichFunctionToRunObj)
{
RunThisFunctionDelegateTimeout whichFunctionToRun =
(RunThisFunctionDelegateTimeout)whichFunctionToRunObj;

whichFunctionToRun(); // launch our function

// notify evnt.WaitOne that we are done with our operation
evnt.Set();

} // end DoTimeoutFunctionStart ()
....
Like I said, I got a lot of this material from that website.

Thank you very much Willy for pointing us in the right direction! :~}

Rob K
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top