System.Timers.Timer - Potential CPU Hog

G

Guest

I have a timer running on our form and what we have seen is users who leave
there application open for more than a day straight will have a response
problem with the UI. We tracked the CPU utilization and the spikes started
off at 1 min intervals every 10 minutes and it increased to 10 minutes
intervals after 3 days having the app open. I'm wording if it's the Timer
that is causing these spikes espically seeing that the user wasn't doing
anything to the app most of the time. See my code below and please let me
know if anyone sees a problem that could be causing the cpu spikes and the
distruption for the users.

Me.QueueTimer.Enabled = True
Me.QueueTimer.Interval = 600000
Me.QueueTimer.SynchronizingObject = Me
******************************************
Private Sub TraderPortal_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Try
subSetupTimer()

Catch exp As Exception
MessageBox.Show(exp.Message.ToString)
End Try
End Sub

Public Sub subSetupTimer()
Try
'Setup the event handler for the timer when it fires
AddHandler QueueTimer.Elapsed, AddressOf TimerFiredForQueue
Catch exp As Exception
ExceptionCall.ExceptionHandling.LogError(exp.Message.ToString)
End Try
End Sub

Public Sub TimerFiredForQueue(ByVal sender As Object, _
ByVal e As System.Timers.ElapsedEventArgs)
Try
QueueTimer.Enabled = False

'Now we need to refresh the intra day view
QueueFlex.Clear(C1.Win.C1FlexGrid.ClearFlags.UserData)
dsNotifications.Clear()

QueueFlex.Redraw = False

Dim parm As New SqlClient.SqlParameter("@BLTID",
Main.oProperties.UsersBankLoanTeamID)

DBCalls.AccessDataLayer.FillGridWithDataset("SelUserNotifications",
Main.oProperties.ConnectionString, dsNotifications, "queue", QueueFlex, parm)

QueueFlex.Redraw = True

FillSplitCalendarItemslocal()

If isFilter Then
btnApplyFilter_Click(sender, e)
Else
ResetCalendar()
End If

QueueTimer.Enabled = True
Catch exp As Exception
MessageBox.Show(exp.Message.ToString)
End Try
End Sub
Was this post helpful to you?
 
M

Mehdi

I have a timer running on our form and what we have seen is users who leave
there application open for more than a day straight will have a response
problem with the UI. We tracked the CPU utilization and the spikes started
off at 1 min intervals every 10 minutes and it increased to 10 minutes
intervals after 3 days having the app open. I'm wording if it's the Timer
that is causing these spikes espically seeing that the user wasn't doing
anything to the app most of the time. See my code below and please let me
know if anyone sees a problem that could be causing the cpu spikes and the
distruption for the users.

There is too little info here to really know if the problem lies there or
not. You're giving us code that uses loads of custom classes and methods
whithout telling us what is what and what is supposed to do what.
At first sight though it doesn't look to me that this piece of code could
cause your problem. A few remarks (based on my interpretation, which might
be wrong, of your code):

1) You're setting your timer's SynchronizingObject property to Me, which I
supposed is a Form. So the timer's elapsed event is executed in the UI
thread. There you seem to access a database to retrieve some data in a
dataset. I don't know where your database is, what data it contains and
what you are doing with it but a database operation can always be a
potentially long running operation. I would do that asynchronously to avoid
freezing the UI.

2) The 'btnApplyFilter_Click(sender, e)' call look very strange to me.
You're not supposed to call control's event handlers directly and certainly
not to call a button's event handler passing a timer's sender and EventArgs
parameters to it. Why don't you move the code executed by this button's
handler to a method and simply call this method instead of the button's
event handler?

3) You don't need to call ToString on Exception.Message. It's already a
string.
 
G

Guest

So if I take off that property SynchronizingObject = Me then I would have to
use a delegate to load my data grid which can't be loaded on a background
thread. Also I am using sql server and it's just refreshing the data in a
bound grid with a quick stored procedure call. Also we had the DBA's have a
trace on the users when the extended spikes ocurred and nothing was going on
at the sql level.

Regarding your items 2 & 3 point taken and I will clean these areas up.

I guess the bottom line as you can see so far is this code doesn't look like
it's causing a progress cpu spike over time.
Thanks
 
J

Jeffrey Tan[MSFT]

Hi MasterBlaster,

Thanks for your feedback.

Normally, we should separate the ADO.net database operation from .Net
winform databinding operation. That is, the database data retrieving and
dataset fill operations should be separated from setting
DataGrid.DataSource to this DataSet.

In GUI application, we should not place lengthy operations in the UI
thread, which will block the UI thread from processing WM_PAINT or other
mouse/keyboard messages. This is the root cause of GUI application with
non-responsible UI. Once the UI thread can run without being blocked, there
should not be any responsibility issue.

Now, in your application, based on the current available information(I am
not sure if it is the root cause), there are 2 lengthy operations:
1. database ADO.net operation(including filling the dataset)
2. winform databinding with dataset operation

Regarding #1, it is very time-consuming, which may serious block the UI
thread. So we'd better place it in a background thread.
Regarding #2, whether it is slow based on the number of data in the
DataSet. If there are much data to display in the winform, we'd better to
implement some customized paging to improve performance. We can place this
operation in UI thread, so that there is no need to do thread safe
marshaling.

#1 Note: dataset is multithread read safe class, for DataSet fill
operation, we should do some synchronization to it.

For more information regarding doing correct multithreading in winform,
please refer to the link below:
"Safe, Simple Multithreading in Windows Forms, Part 1"
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/htm
l/winforms06112002.asp

Hope this helps!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

The amount of data is minimal (like 15 records) which is nothing. I don't
know if I described our problem correctly. The timer processing is fine for a
while but over time the cpu spikes last longer and longer at first the spike
will last for 15 seconds and if you keep the app open for two straight days
it gets up to 9 minutes of a cpu spike. I guess my question is would the
timer processing I'm doing cause this type of behavior? I know I can load the
dataset on the background thread but I have to load the grid on the ui thread
though.
 
J

Jeffrey Tan[MSFT]

Hi MasterBlaster,

Thanks for your feedback.

Can you show me in details, how you detect the cpu spikes? Actually, from
technical perspective, I just can not understand the cpu spikes very well.
Also, I do not think the timer has such strange behavior(unless there is
any definite reproduce way).

Normally, in Windows CPU will give every thread its running slice, and
unless the UI thread can not process its WM_PAINT message,(because of doing
some other work or just waiting on something as deadlock), the UI will
always be responsible.

So we need more information regarding your scenario. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

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