2

Using a C#, WPF, MVVM, Prism, MEF. I need the external effects (I have it from the View is called Dispose ()) to free resources in the ViewModel, used in the View. I use something like the following code:

public class MyViewModel: IDisposable, IMyViewModel, ...
{
    private bool disposed = false;

    private System.Timers.Timer timer;

    public MyViewModel()
    {
        timer = new System.Timers.Timer();
        timer.Interval = 100;
        //timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        timer.Start();
    }

    public void Dispose()
    {
        Dispose(true);

        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if(!this.disposed)
        {
            if(disposing)
            {
                // Dispose managed resources.
                timer.Dispose();
                timer = null;
                //GC.KeepAlive(timer);
                //GC.Collect();
            }

            disposed = true;
        }
    }

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

As such, the View and ViewModel instances are not destroyed and there is a memory leak. If you delete the interface and its methods IDisposable, the View and ViewModel deleted successfully.

I using ANTS Memory Profiler. On next diagram you can see three instance, from DisposableReflecationComposablePart, but must be a one instance.

enter image description here

I can not understand what was happening. Any ideas?

Edit: I understand that my statements explain the problem is the link: http://mef.codeplex.com/wikipage?title=Parts%20Lifetime&referringTitle=Guide

in the following sentence: Thus, the container will not hold references to parts it creates unless one of the following is true:

 The part is marked as Shared
 The part implements IDisposable
 One or more imports is configured to allow recomposition
Ivan
  • 173
  • 1
  • 4
  • 18
  • How do you know that without IDisposable the ViewModel is deleted successfully? Something would at least have to stop the timer. Anyway, explicit destructors are generally bad design, since they might [never be called](http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx). It's not like C++. – Clemens Feb 07 '12 at 11:13
  • Yes, this is C#. I edited my question and add image. – Ivan Feb 07 '12 at 11:25
  • When you observe the leak, i.e. with IDisposable implemented, do you have an event handler attached for Timer.Elapsed, or is it still commented out? – Clemens Feb 07 '12 at 11:33
  • Timer.Elapsed is it still commented, you can even remove all that relates to the timer, and will experience a memory leak, and if you remove IDisposable from the recent findings of his methods, then memory leaks will not be. I could do without, and IDisposable, but a matter of principle and I believe that through the IDisposable better, more correct) – Ivan Feb 07 '12 at 11:48
  • 2
    Without having a solution for your concrete problem, i think you are misunderstanding the purpose of [IDisposable](http://msdn.microsoft.com/en-us/library/System.IDisposable.aspx): `The primary use of this interface is to release unmanaged resources` and you don't have unmanaged resources. Moreover, `Dispose` is never called automatically, neither is a destructor called automatically, but only if an object is ready for garbage collection. Your approach is not "more correct", it is not correct at all unless you explicitly call Dispose somewhere in your code. – Clemens Feb 07 '12 at 11:56
  • As you say, I can not do so: myObject.Dispose()? It would be wrong? – Ivan Feb 07 '12 at 12:16
  • Ah, i just saw you`re saying that you are explicitely calling Dispose from your View. What about not calling `GC.SuppressFinalize(this)` in `Dispose()`. It's not clear what that would be good for, since the default Finalize doesn't do anything. But maybe suppressing it has some side effect on the garbage collector. – Clemens Feb 07 '12 at 12:17
  • Thank you. So far I have not found an answer to your question. – Ivan Feb 07 '12 at 12:25
  • over optimization? unless you're using this class everywhere, i don't think it's going to be a prob.. – Jake Berger Feb 07 '12 at 17:42
  • I often have to delete and create instances of this class. – Ivan Feb 08 '12 at 01:19

1 Answers1

3

See my question here for answers that may help you.

I was in a similar situation and ended up using a custom interface, let's say ICleanup, instead of IDisposable in order to avoid having MEF keeping a reference to my views.

I consider this to be a very big flaw in MEF's design. I thought they would at least let each part decide for itself whether a reference to it should be kept by using a certain attribute or by implementing an interface...

Community
  • 1
  • 1
Adi Lester
  • 24,731
  • 12
  • 95
  • 110
  • 1
    For some reason I have not seen this issue. I have to do the same and came to use his interface (in place of IDisposable). – Ivan Feb 09 '12 at 04:26