0

I am using a class library to simulate and process data and return results via triggered events.

DataProcessor _dataProcessor

In it I am using a DispatcherTimer to simulate data and raise events when simulated data is available and ready to be pushed to GUI.

Was wondering how best to kill the _dataProcessor?

My experience is that setting

_dataProcessor = null;

does not kill the DispatcherTimer. The events are still raised and still passed up to the GUI.

Do I have to stop/null out the DispatcherTimer before the GAC will dispose of the class library?

Thank you for any guidance as I'm not sure the best way to approach this task in general, yet alone terminating the instance of the class library on demand.

faldeland
  • 587
  • 6
  • 20

4 Answers4

2

A DispatcherTimer keeps itself alive while it is enabled, even if you don't keep a reference to it. Rather important, nobody expects a timer to stop raising events unless asking it explicitly to Stop(). It does so by adding a reference to itself into a private List<> kept by the Dispatcher. And removing that reference in Stop().

Which in turn ensures that your DataProcessor will not get garbage collected if it has a non-static Tick event handler. Setting the reference you keep to null has no effect, the references kept by Dispatcher and the event delegate keep the object alive.

You'll need to add a method to DataProcessor that stops the timer.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • This has been my experience and answers my question. I have implemented such a method to stop the timer and it seems to do the trick. I suspect my downfall is the DispatcherTimer so I will investigate other timer options. – faldeland Jul 23 '12 at 20:26
1

Your DataProcessor class should implement the IDisposable interface - http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

Then you could call DispatchTimer.Stop() when you want to kill your DataProcessor class.

public class DataProcessor : IDisposable
{
    private bool disposed = false; 
    DispatchTimer timer;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                if(timer != null)
                   timer.Stop();
            }

            disposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~DataProcessor()
    {
        Dispose(false);
    }
}

Use it:

using(DataProcessor process = new DataProcessor)
{
     //etc...
} //stop timer
EkoostikMartin
  • 6,831
  • 2
  • 33
  • 62
0

I do not find DispatcherTimer in standard .NET class list, so I assume it's your own class. If this is the case then standard pattern is for your DispatcherTimer class to implement IDisposable, and then call _dataProcessor.Dispose() when you no longer need it, or dispose it by means of using keyword

galets
  • 17,802
  • 19
  • 72
  • 101
0

galets and EkoostikMartin have answered the question already. Let me explain the using-statement in more detail. This same keyword is used in two different statements in c#. I won't discuss using <namesapce>; here. The other can be used in methods. Assuming that DispatchTimer implements IDisposable:

using (var timer = new DispatchTimer()) {
    timer.Start();
    // ... do something here.
}

does the same as

{
   var timer = new DispatchTimer();
   try {
       timer.Start();
       // ... do something here.
   } finally {
       if (timer != null) {
           ((IDisposable)timer).Dispose();
       }
   }
}

It gives you a safe way to close or terminate something you have opened or started. Dispose will even be called if an exception occurs within the using block or if the using block if left by return for example.


UPDATE

As EkoostikMartin sais in his comment, DispatchTimer does not implement IDisposable but you can easily create a disposable version of it

public class DisposableDispatchTimer : DispatchTimer, IDisposable
{
    public void Dispose()
    {
        Stop();
    }
}
Community
  • 1
  • 1
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • `DispatchTimer` is a WPF class though, and it doesn't implement IDisposable. This makes your example confusing. – EkoostikMartin Jul 23 '12 at 20:13
  • @EkoostikMartin: OK, you are right. I found `DispatchTimer` in `System.Windows.Threading`. It does in fact not implement `IDisposable` as you said. But since the class is not sealed, you could easily derive your own class from it and implement `IDisposable`. – Olivier Jacot-Descombes Jul 23 '12 at 20:22