Mattersphere Developers Forum
Would you like to react to this message? Create an account in a few clicks or log in to continue.

Go down
avatar
Lynne Harding
Posts : 335
Join date : 2018-12-20

System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To Empty System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To

Mon 27 Jan 2020 - 8:44
System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To
This is a continuation of the problems I've had with an external application.
Please see HERE for further details.
In this application I have added System.Windows.Forms.Timer so that the emails are sent to the Fee Earners once a day and consists of the following code...
//********************************************************************
// Create a private global timer
//--------------------------------------------------------------------
// SPR 25-04-2013
// Garbage Collection is romoving the timer.
// It needs to be referenced within the software so change from...
// private System.Windows.Forms.Timer scheduleTimer; to ...
// private static System.Windows.Forms.Timer scheduleTimer;
//********************************************************************
private static System.Windows.Forms.Timer scheduleTimer;
private void InitialiseTimer()
{
try
{
const float MILLI_SECONDS_IN_A_SECOND = 1000.0F;
const float SECONDS_IN_A_MINUTE = 60.0F;
//****************************************************************
// Randomly picked value that seems to work
//****************************************************************
float INTERVAL_TIME_IN_MINUTES = 0.17F;
//****************************************************************
// Calulate timer interval. Calculation made complex so it is easy
// to change in a build.
//****************************************************************
int TIMER_INTERVAL_TIME = Convert.ToInt32(INTERVAL_TIME_IN_MINUTES * SECONDS_IN_A_MINUTE * MILLI_SECONDS_IN_A_SECOND);
//****************************************************************
// Create an event handler for the timer.
//****************************************************************
scheduleTimer = new System.Windows.Forms.Timer();
scheduleTimer.Tick += new EventHandler(scheduleTimer_Tick);
//****************************************************************
// Set interval and start timer.
//****************************************************************

scheduleTimer.Interval = TIMER_INTERVAL_TIME; scheduleTimer.Start();

//****************************************************************
// SPR 26-04-2013
// Set timer enabled = true to stop timer being garbage collected.
//**************************************************************** scheduleTimer.Enabled = true;
}
catch (Exception ex)
{
string THE_CARRIAGE_RETURN = System.Environment.NewLine; string myTitle = “Error Message - “ + ex.TargetSite”;
string myMessage = @”“;

myMessage += string.Format(“{0}{1}{2}{3}”, “ERROR: An exception of type: “, ex.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN); myMessage += string.Format(“{0}{1}{2}{3}”, “Occurred in method: “, ex.TargetSite, THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN); myMessage += string.Format(“{0}{1}{2}{3}”, “In the following module: “, this.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN); myMessage += string.Format(“{0}{1}”, “Message: “, ex.Message.ToString());

System.Windows.Forms.MessageBox.Show(myMessage, myTitle);
}
}

//********************************************************************
// SPR 19-02-2013
// This event handler if fired by the timer every
// [TIMER_INTERVAL_TIME] milliseconds
//******************************************************************** private void scheduleTimer_Tick(object sender, EventArgs e)
{
try
{
//****************************************************************
// Constants used in calculations
//**************************************************************** const int LAST_RUN_FACTOR = -1;
const int CURRENT_TIME_PLUS = 30;

//****************************************************************
// Get the time that you want the schedule to start using 24 hour
// clock. The date is not displayed.
// e.g. 25-04-2013 06:12:00
//**************************************************************** System.DateTime scheduledRun = this.dtpScheduledTime.Value;

//****************************************************************
// Calculate the datetime of last scheduled run == current
// scheduled run - 1 day
// e.g. 24-04-2013 06:12:00
//****************************************************************
System.DateTime lastRun = this.dtpScheduledTime.Value.AddDays(LAST_RUN_FACTOR);

//****************************************************************
// Calculate a factor using current scheduled run + 30 seconds
// e.g. 25-04-2013 06:12:30
//****************************************************************
System.DateTime scheduledRunPlusFactor = scheduledRun.AddSeconds(CURRENT_TIME_PLUS);

//****************************************************************
// Get current datatime
// e.g. Ex1 - 25-04-2013 05:12:00
// e.g. Ex2 - 25-04-2013 06:12:00
// e.g. Ex3 - 25-04-2013 06:12:05
//**************************************************************** System.DateTime currentTime = System.DateTime.Now;

//****************************************************************
// Create a Timespan object = current time - time of the last run.
// Timespan is a struc...
// [days, hours, minutes, seconds, milliseconds]
// Ex1 - [0, 23, 0, 0, 0]
// Ex2 - [1, 0, 0, 0, 0]
// Ex3 - [1, 0, 0, 30, 0]
//**************************************************************** System.TimeSpan sinceLastRun = (currentTime - lastRun);

//****************************************************************
// Ex1:
// (25-04-2013 05:12:00 > 25-04-2013 06:12:00) - False
// (25-04-2013 05:12:00 < 25-04-2013 06:12:10) - True
//
// Ex2
// (25-04-2013 06:12:00 > 25-04-2013 06:12:00) - False
// (25-04-2013 06:12:00 < 25-04-2013 06:12:30) - True
//
// Ex3
// (25-04-2013 06:12:05 > 25-04-2013 06:12:00) - True
// (25-04-2013 06:12:05 < 25-04-2013 06:12:30) - True
//****************************************************************
if ((currentTime > scheduledRun) && (currentTime < scheduledRunPlusFactor))
{

if ((sinceLastRun.Hours == 0))
{
EmailingReminders();
}
}
}
catch (Exception ex)
{
string THE_CARRIAGE_RETURN = System.Environment.NewLine; string myTitle = “Error Message - “ + ex.TargetSite”;
string myMessage = @”“;

myMessage += string.Format(“{0}{1}{2}{3}”, “ERROR: An exception of type: “, ex.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN); myMessage += string.Format(“{0}{1}{2}{3}”, “Occurred in method: “, ex.TargetSite, THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN); myMessage += string.Format(“{0}{1}{2}{3}”, “In the following module: “, this.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN); myMessage += string.Format(“{0}{1}”, “Message: “, ex.Message.ToString());

System.Windows.Forms.MessageBox.Show(myMessage, myTitle);
}
}

When I test the app. The scheduler works. For instance, If current time is 13:15 and I set the schedule for 13:20 the emails are sent, but when I execute overnight, I come in to the office and the scheduler has not executed and there are no exception messages.
The best I can work out is that the timer has been garbage collected, but After Googling about, I think I have written the code so that the Timer is not being GC'ed.

What am I doing wrong?
avatar
Lynne Harding
Posts : 335
Join date : 2018-12-20

System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To Empty Response from TR

Mon 27 Jan 2020 - 8:45
Hi,
Will sinceLastRun.Hours ever = 0? I think it will only be 0 when run less than an hour after the start time.
I would add an else to the following and output some diagnostic data
if ((currentTime > scheduledRun) && (currentTime < scheduledRunPlusFactor))
{
if ((sinceLastRun.Hours == 0))
{
EmailingReminders();
}
else
{
Output(“(sinceLastRun.Hours == 0) is FALSE”); Output(sinceLastRun.Hours.ToString());
}

}
else
{
Output(“(currentTime > scheduledRun) && (currentTime < scheduledRunPlusFactor) is FALSE”);
}


avatar
Lynne Harding
Posts : 335
Join date : 2018-12-20

System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To Empty Re: System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To

Mon 27 Jan 2020 - 8:45
Richard
Thanks for your help. You were correct. The code as written will only work if the scheduled time selected was within an hour of the application's start time. I had to rewrite the code.
The method now calculates a time in milliseconds until the next scheduled run of the emailing method and sets the timer's interval to this value. Thi means that the Event Handler only fires once a day instead of checking against an arbitrary value every 11 seconds.
Here is the code...


//*****************************************************************************
// SPR 19-02-2013
// Creating all the code necessary for the sceduling part of the
// software
//*****************************************************************************

//*****************************************************************************
// Create a private global timer
//-----------------------------------------------------------------------------
// SPR 25-04-2013
// Garbage Collection is romoving the timer.
// It needs to be referenced within the software so change from...
// private System.Windows.Forms.Timer scheduleTimer; to ...
// private static System.Windows.Forms.Timer scheduleTimer;
//***************************************************************************** private static System.Windows.Forms.Timer scheduleTimer;

//*****************************************************************************
// SPR 07-05-2013
// Another try to make scheduling work. First add a private static
// Timespan object.
//***************************************************************************** private static System.TimeSpan executionTime = new System.TimeSpan();

//*****************************************************************************
// SPR 07-05-2013

// A rewrite of scheduling the application to execute once a day. We
// will require a new inialisation process.
//***************************************************************************** private void InitialiseTimer()
{
try
{
executionTime = TargetTime();

//*********************************************************************
// Create an event handler for the timer.
//********************************************************************* scheduleTimer = new System.Windows.Forms.Timer(); scheduleTimer.Tick += new EventHandler(scheduleTimer_Tick);

//*********************************************************************
// Set interval and start timer.
//********************************************************************* scheduleTimer.Interval =
Convert.ToInt32(MillisecondsToNextTargetTime(executionTime)); scheduleTimer.Start();
//*********************************************************************
// SPR 07-05-2013
// Set timer enabled = true to stop timer being garbage collected.
//********************************************************************* scheduleTimer.Enabled = true;
}
catch (Exception ex)
{
string THE_CARRIAGE_RETURN = System.Environment.NewLine; string myTitle = “Error Message - “ + ex.TargetSite”;
string myMessage = @”“;

myMessage += string.Format( “{0}{1}{2}{3}”
, “ERROR: An exception of type: “
, ex.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format( “{0}{1}{2}{3}”
, “Occurred in method: “
, ex.TargetSite, THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format(

“{0}{1}{2}{3}”
, “In the following module: “
, this.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format( “{0}{1}”
, “Message: “, ex.Message.ToString());

System.Windows.Forms.MessageBox.Show(myMessage, myTitle);
}
}

//*****************************************************************************
// SPR 07-05-2013
// Another try to make scheduling work. This method returns a target
// time in a TimeSpan object, which will be used to calculate timer
// interval. Initially default all values to 0
//***************************************************************************** private System.TimeSpan TargetTime()
{
const int DEFAULT_DAYS = 0; const int DEFAULT_HOURS = 0; const int DEFAULT_MINUTES = 0; const int DEFAULT_SECONDS = 0;
const int DEFAULT_MILLISECONDS = 0;

System.TimeSpan myTargetTime = new System.TimeSpan(
DEFAULT_DAYS
, DEFAULT_HOURS
, DEFAULT_MINUTES, DEFAULT_SECONDS, DEFAULT_MILLISECONDS);

try
{
//*********************************************************************
// Get scheduled time from control dtpScheduledTime
//********************************************************************* System.DateTime scheduledTime = this.dtpScheduledTime.Value;

//*********************************************************************
// Extract time from above and set myTargetTime object to have
// same time.
//********************************************************************* int SCHEDULED_DAYS = 0;
int scheduledHours = scheduledTime.Hour;
int scheduledMinutes = scheduledTime.Minute;

int scheduledSeconds = scheduledTime.Second;
int scheduledMilliseconds = scheduledTime.Millisecond;

myTargetTime =
new System.TimeSpan( SCHEDULED_DAYS
, scheduledHours
, scheduledMinutes
, scheduledSeconds, scheduledMilliseconds);

}
catch (Exception ex)
{
string THE_CARRIAGE_RETURN = System.Environment.NewLine; string myTitle = “Error Message - “ + ex.TargetSite”;
string myMessage = @”“;

myMessage += string.Format( “{0}{1}{2}{3}”
, “ERROR: An exception of type: “
, ex.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format( “{0}{1}{2}{3}”
, “Occurred in method: “
, ex.TargetSite, THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format( “{0}{1}{2}{3}”
, “In the following module: “
, this.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format( “{0}{1}”
, “Message: “, ex.Message.ToString());

System.Windows.Forms.MessageBox.Show(myMessage, myTitle);
}

return myTargetTime;
}

//*****************************************************************************
// SPR 07-05-2013
// Calculates how long till next scheduled tick of the timer
//*****************************************************************************

private double MillisecondsToNextTargetTime(TimeSpan targetTime)
{
System.DateTime myDateTime = System.DateTime.Today.Add(targetTime);

try
{
const int NO_DAYS_TO_ADD = 1;
if (System.DateTime.Now > myDateTime)
{
//*****************************************************************
// we're already past todays target time; set it up for
// tomorrow
//***************************************************************** myDateTime = myDateTime.AddDays(NO_DAYS_TO_ADD);
}

//*********************************************************************
// This code is just in case we want to only execute the reminder
// week days only.
//*********************************************************************
/*

while (
myDateTime.DayOfWeek == DayOfWeek.Saturday
|| myDateTime.DayOfWeek == DayOfWeek.Sunday)
{
myDateTime = myDateTime.AddDays(NO_DAYS_TO_ADD);
}

*/
}
catch (Exception ex)
{
string THE_CARRIAGE_RETURN = System.Environment.NewLine; string myTitle = “Error Message - “ + ex.TargetSite”;
string myMessage = @”“;

myMessage += string.Format( “{0}{1}{2}{3}”
, “ERROR: An exception of type: “
, ex.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format( “{0}{1}{2}{3}”
, “Occurred in method: “
, ex.TargetSite, THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);


myMessage += string.Format( “{0}{1}{2}{3}”
, “In the following module: “
, this.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);

myMessage += string.Format( “{0}{1}”
, “Message: “, ex.Message.ToString());

System.Windows.Forms.MessageBox.Show(myMessage, myTitle);
}

return myDateTime.Subtract(DateTime.Now).TotalMilliseconds;
}

//*****************************************************************************
// SPR 07-05-2013
// This event handler if fired by the timer once. The interval is the
// number of milliseconds till next execution time.
//***************************************************************************** private void scheduleTimer_Tick(object sender, EventArgs e)
{
try
{
//*********************************************************************
// SPR 07-05-2031
// Stop the timer and then carry out Emailing Reminders
//********************************************************************* scheduleTimer.Stop();
EmailingReminders();

//*********************************************************************
// Set interval and start timer.
//********************************************************************* scheduleTimer.Interval =
Convert.ToInt32(MillisecondsToNextTargetTime(executionTime)); scheduleTimer.Start();
//*********************************************************************
// SPR 07-05-2013
// Set timer enabled = true to stop timer being garbage collected.
//********************************************************************* scheduleTimer.Enabled = true;
}

catch (Exception ex)
{
string THE_CARRIAGE_RETURN = System.Environment.NewLine;
string myTitle = “Error Message - “ + ex.TargetSite”;
string myMessage = @”“;
myMessage += string.Format(
“{0}{1}{2}{3}”
, “ERROR: An exception of type: “
, ex.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);
myMessage += string.Format(
“{0}{1}{2}{3}”
, “Occurred in method: “
, ex.TargetSite, THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);
myMessage += string.Format(
“{0}{1}{2}{3}”
, “In the following module: “
, this.GetType(), THE_CARRIAGE_RETURN, THE_CARRIAGE_RETURN);
myMessage += string.Format(
“{0}{1}”
, “Message: “, ex.Message.ToString());
System.Windows.Forms.MessageBox.Show(myMessage, myTitle);
}
}
Sponsored content

System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To Empty Re: System.Windows.Forms.Timer Seems To Be Garbage Collected Even When coded not To

Back to top
Permissions in this forum:
You cannot reply to topics in this forum