From: Daniel Lidstrom on
Hello,

I am trying to understand how the garbage collector works. To do this I
created a simple test with a timer. I create a timer and then release all
references leading to this timer, then I force a garbage collection. To my
surprise the timer is still sparking off events! Here's the code:


using System.Timers;
using System;

public class TimerTest
{
public TimerTest()
{
var timer = new Timer(1000);
timer.Elapsed += (o, e) => { Console.WriteLine("Timer elapsed"); };
timer.Start();
}

public static void Main()
{
{
var timerTest = new TimerTest();
}

Console.ReadLine();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect(); // necessary? does not seem to help
Console.ReadLine();
}
}


Can someone please explain why the Elapsed event is still firing after the
first ReadLine()? Thanks in advance!

Regards,

Daniel Lidstr�m


From: Mr. Arnold on
Daniel Lidstrom wrote:
> Hello,
>
> I am trying to understand how the garbage collector works. To do this I
> created a simple test with a timer. I create a timer and then release
> all references leading to this timer, then I force a garbage collection.
> To my surprise the timer is still sparking off events! Here's the code:
>
>

I guess you can just set the Timer to null Timer=null that should kill it.


Here is a link that I got from a developer on the job as we talked about
how a Web server can still keep objects in memory, such as a ADO.NET
Entity Framework compiled query object, and it's there the next time the
stateless Web application wants to use that object again, and not having
to recompile the query object again, because it's always in (static)
memory due to the W3WP.exe is always executing.

<http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/>
From: Daniel Lidstrom on
"Mr. Arnold" <Arnold(a)Arnold.com> wrote in message
news:enGFmQ3ELHA.1316(a)TK2MSFTNGP02.phx.gbl...
>
> I guess you can just set the Timer to null Timer=null that should kill it.

Neither setting timer nor timerTest to null helped in this case. Even if it
had helped I think that in a larger
application it becomes impractical to have to set unused references to null.

>
> Here is a link that I got from a developer on the job as we talked about
> how a Web server can still keep objects in memory, such as a ADO.NET
> Entity Framework compiled query object, and it's there the next time the
> stateless Web application wants to use that object again, and not having
> to recompile the query object again, because it's always in (static)
> memory due to the W3WP.exe is always executing.
>
> <http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/>

Thanks for the reference!

Daniel

From: Andrew Baker on
Because the timer is active (enabled), there's still a live reference to
it, preventing the garbage collection. You've not got direct access to
this reference, 'the system' has got one inside the workings of the .net
framework somewhere.

On 24/06/2010 08:41, Daniel Lidstrom wrote:
> Hello,
>
> I am trying to understand how the garbage collector works. To do this I
> created a simple test with a timer. I create a timer and then release
> all references leading to this timer, then I force a garbage collection.
> To my surprise the timer is still sparking off events! Here's the code:
>
>
> using System.Timers;
> using System;
>
> public class TimerTest
> {
> public TimerTest()
> {
> var timer = new Timer(1000);
> timer.Elapsed += (o, e) => { Console.WriteLine("Timer elapsed"); };
> timer.Start();
> }
>
> public static void Main()
> {
> {
> var timerTest = new TimerTest();
> }
>
> Console.ReadLine();
> GC.Collect();
> GC.WaitForPendingFinalizers();
> GC.Collect(); // necessary? does not seem to help
> Console.ReadLine();
> }
> }
>
>
> Can someone please explain why the Elapsed event is still firing after
> the first ReadLine()? Thanks in advance!
>
> Regards,
>
> Daniel Lidstr�m
>
>

From: Mr. Arnold on
Daniel Lidstrom wrote:
> "Mr. Arnold" <Arnold(a)Arnold.com> wrote in message
> news:enGFmQ3ELHA.1316(a)TK2MSFTNGP02.phx.gbl...
>>
>> I guess you can just set the Timer to null Timer=null that should kill
>> it.
>
> Neither setting timer nor timerTest to null helped in this case. Even if
> it had helped I think that in a larger
> application it becomes impractical to have to set unused references to
> null.

I guess you have never worked in the COM, DCOM or COM+ environment, back
in the day for large applications, where objects had to be set manually
to null to release resources. These technologies are still being used to
this day.