0

present code is currently structured as follows:

System.Timers.Timer myTimer;

public void FirstMethod() {
  myTimer;= new System.Timers.Timer();
  myTimer.start();
  SecondMethod();
}

public void SecondMethod(){
  //several things happen here and then
  myTimer.stop();  
}

I've been advised that I could use using to correctly garbage collect the Timer object. So I've tried to apply something like the following to my code (taken from here):

using (SomeClass someClass = new SomeClass())
{  
someClass.DoSomething();  
}  

I assume the following will error because myTimer is not known by SecondMethod()?

public void FirstMethod() {
  using (System.Timers.Timer myTimer = new System.Timers.Timer())   
  { 
  myTimer.start();
  SecondMethod();
  }
}

public void SecondMethod(){
//several things happen here and then
myTimer.stop();  
}
Community
  • 1
  • 1
whytheq
  • 34,466
  • 65
  • 172
  • 267
  • Why does SecondMethod need to know about myTimer? The dispose will stop the timer. – payo Apr 17 '12 at 21:41
  • IIRC, `using` doesn't take care of garbage collection, it just calls `Dispose` in the object. So unless there is actually a resource that the timer uses, there's no real benefit in `using`. – Ken Wayne VanderLinde Apr 17 '12 at 21:42
  • @KenWayneVanderLinde correct, dispose does no GC work (except for marshalled data specific to that class). – payo Apr 17 '12 at 21:43
  • @payo ...I'm new to c# and what you've said is effectively my question. – whytheq Apr 17 '12 at 21:44
  • @whytheq: Really? Because that's not what you have asked. If you need to know the difference between managed and native resource management there are many threads about it on SO already. – Ed S. Apr 17 '12 at 21:47

5 Answers5

3

You can only use using if the object should be disposed (=destroyed) after the using block ends. A timer usually lasts longer than that (as in your example).

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72
2

You wrap an object that implements the IDisposable interface in a using block when it makes sense to do so. In this case it does not because the object must be valid at a higher scope. Remember, a using statement is just shorthand (syntactic sugar) for this:

var myDisposableObj = new Whatever();
try
{
    // use myDisposableObj.  If an exception is thrown
    // in here somewhere the call to Dispose() still occurs.
}
finally
{
    myDisposableObj.Dispose();
}

In your case you need to ensure that you call Dispose() on the object when you are done with it (and in a manner that accounts for exceptions which may be thrown that would prevent the call to Dispose() from taking place). You need the Timer to stick around for a while, so a using block is out of the question.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • System.Threading.Timer does implement IDisposable - maybe whatever @whytheq is trying to accomplish could take advantage of it? http://msdn.microsoft.com/en-us/library/saba8ksx%28v=vs.90%29.aspx – Kris Krause Apr 17 '12 at 21:52
  • @EdS. [here](http://stackoverflow.com/questions/475763/is-it-necessary-to-dispose-system-timers-timer-if-you-use-one-in-your-applicatio) seemed to suggest that it is IDisposable – whytheq Apr 17 '12 at 21:56
  • `Timer` inherits from `Component` which implements `IDisposable`. – Ken Wayne VanderLinde Apr 17 '12 at 22:03
1

using can only be used on an object that implements IDisposable and it will automatically be disposed at the end of the using block. If you need to use that object anywhere else, then you cannot use using.

In your example, not only will your original object not be known in other methods, but it'll be deleted.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • In the full code `secondMethod` is actually a method which is subscribed to one of the Timer's events - there is a conditional statement in `secondMethod` and the `Timer`can be stopped under certainconditions – whytheq Apr 17 '12 at 21:48
  • Why not simply add the timer component to your form? (Is this a WebForm app?) I'm not sure why you are creating the control dynamically when you can simply turn it on and off. Note: I use `using` all the time and like it, but the restrictions described above means I can't use it anywhere. – Jonathan Wood Apr 17 '12 at 22:25
  • it's a windows form. From what I've read System.Timers.Timer does everything that the forms Timer does and more - so I'm using that. Thanks for the help - I'm just playing around getting familiar with various objects – whytheq Apr 17 '12 at 22:30
1

Yes, you are right. Your code is wrong because myTimer is declared as a local variable and it's only available in the using scope. You should change your code to sth. like this

public void FirstMethod() {
  using (System.Timers.Timer myTimer = new System.Timers.Timer())   
  { 
  myTimer.start();
  SecondMethod(myTimer);
  }
}

public void SecondMethod(System.Timers.Timer theTimer){
    //several things happen here and then
    theTimer.stop();  
}
Michael Yin
  • 1,764
  • 13
  • 13
  • Dan suggested this below Michael and got shouted at! – whytheq Apr 17 '12 at 21:49
  • This is just goofy code as it doesn't even use the timer in any reasonable fashion. – Ed S. Apr 17 '12 at 21:51
  • @EdS. my last post in another [thread](http://stackoverflow.com/questions/10170448/introducing-timer-means-its-multi-threaded) has the full code. You can see in the `keepingTime()` method I've attempted to use using...but this thread has confirmed I'll need to find a different approach – whytheq Apr 17 '12 at 22:07
1

The "using pattern" is used to automatically call Dispose when the implementing object is no longer in scope. Dispose is used to clean up any unmanaged resources. Finalize is what the garbage collector calls before the object is "collected".

You could try to "force" collection, however -

"It is possible to force garbage collection by calling Collect, but most of the time, this should be avoided because it may create performance issues."

So you need SecondMethod to have "access" to myTimer?

Kris Krause
  • 7,304
  • 2
  • 23
  • 26
  • exactly Kris - SecondMethod is actually a method which a Timer event is subscribed to. But if certain contitions are true then SecondMethod should stop the Timer. All that bit works but now I'm trying to make sure the garbage gets collected ok and am looking for alternatives – whytheq Apr 17 '12 at 22:01