---
title: "Model-View-ViewModel (MVVM) - Part 2 - IDisposable - Muhammad Rehan Saeed"
description: "Implementing IDisposable correctly is ridiculously hard. A Disposable base class can make it easier. Using IDisposable in Model-View-ViewModel (MVVM) really helps."
canonical_url: "https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/"
last_updated: "2014-06-13T00:00:00+00:00"
meta:
  author: "Muhammad Rehan Saeed"
  keywords: ".NET,Base Class Library,BCL,C#,Design Patterns,IDisposable,Model-View-ViewModel (MVVM),MVVM,Reactive Extensions,Rx"
  "og:description": "Implementing IDisposable correctly is ridiculously hard. A Disposable base class can make it easier. Using IDisposable in Model-View-ViewModel (MVVM) really helps."
  "og:image": "https://rehansaeed.com/_og/s/o_744207fb012b93f0.png"
  "og:image:alt": "Model-View-ViewModel (MVVM) - Part 2 - IDisposable - Muhammad Rehan Saeed"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "Model-View-ViewModel (MVVM) - Part 2 - IDisposable"
  "twitter:image": "https://rehansaeed.com/_og/s/o_744207fb012b93f0.png"
  "twitter:image:alt": "Model-View-ViewModel (MVVM) - Part 2 - IDisposable - Muhammad Rehan Saeed"
---

> Index of every page on this site: [llms.txt](https://rehansaeed.com/llms.txt)

# [Model-View-ViewModel (MVVM) - Part 2 - IDisposable](https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/)

Posted 13 June 2014 - **4 min read**

![MVVM](https://rehansaeed.com/_ipx/f_png&s_2560x1440/images/hero/MVVM-1366x768.png)

1. [Model-View-ViewModel (MVVM) - Overview](https://rehansaeed.com/model-view-viewmodel-mvvm-part1-overview/)
2. [Model-View-ViewModel (MVVM) - IDisposable](https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/)
3. [Model-View-ViewModel (MVVM) - INotifyPropertyChanged](https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/)
4. [Model-View-ViewModel (MVVM) - INotifyDataErrorInfo](https://rehansaeed.com/model-view-viewmodel-mvvm-part4-inotifydataerrorinfo/)

View models these days interact with all kinds of precious resources like Compasses and the GPS. Implementing `IDisposable` is an important pattern you can follow to dispose of these resources cleanly. Freeing them up to be used elsewhere and saving the users battery (Particularly important on mobile devices). Using the `IDisposable` interface in the Model-View-ViewModel (MVVM) pattern is a wise decision.

Implementing `IDisposable` **correctly** is ridiculously hard. If you don't know how hard it really is, I recommend reading the top comment on [this](http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface) Stack Overflow article.

Implementing [IDisposable](http://msdn.microsoft.com/en-GB/library/system.idisposable.aspx) is one of the rare times in C# where a developer has to use [C# Destructors](http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx) and also one of the few times when we have to tickle the garbage collector to stop it from trying to release the unmanaged resources twice by calling [SuppressFinalize](http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize%28v=vs.110%29.aspx) on [GC](http://msdn.microsoft.com/en-us/library/system.gc%28v=vs.110%29.aspx).

Having to write this code repeatedly is difficult and error prone, so how about a base class?

```cs
namespace Framework.ComponentModel
{
    using System;
    using System.Reactive;
    using System.Reactive.Linq;
    using System.Reactive.Subjects;

    /// <summary>
    /// Base class for members implementing <see cref="IDisposable"/>.
    /// </summary>
    public abstract class Disposable : IDisposable
    {
        private bool isDisposed;
        private Subject<Unit> whenDisposedSubject;

        /// <summary>
        /// Finalizes an instance of the <see cref="Disposable"/> class. Releases unmanaged
        /// resources and performs other cleanup operations before the <see cref="Disposable"/>
        /// is reclaimed by garbage collection. Will run only if the
        /// Dispose method does not get called.
        /// </summary>
        ~Disposable() => this.Dispose(false);

        /// <summary>
        /// Gets the when errors changed observable event. Occurs when the validation errors have changed for a property or for the entire object.
        /// </summary>
        /// <value>
        /// The when errors changed observable event.
        /// </value>
        public IObservable<Unit> WhenDisposed
        {
            get
            {
                if (this.IsDisposed)
                {
                    return Observable.Return(Unit.Default);
                }
                else
                {
                    if (this.whenDisposedSubject == null)
                    {
                        this.whenDisposedSubject = new Subject<Unit>();
                    }

                    return this.whenDisposedSubject.AsObservable();
                }
            }
        }

        /// <summary>
        /// Gets a value indicating whether this <see cref="Disposable"/> is disposed.
        /// </summary>
        /// <value><c>true</c> if disposed; otherwise, <c>false</c>.</value>
        public bool IsDisposed => this.isDisposed;

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            // Dispose all managed and unmanaged resources.
            this.Dispose(true);

            // Take this object off the finalization queue and prevent finalization code for this
            // object from executing a second time.
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Disposes the managed resources implementing <see cref="IDisposable"/>.
        /// </summary>
        protected virtual void DisposeManaged()
        {
        }

        /// <summary>
        /// Disposes the unmanaged resources implementing <see cref="IDisposable"/>.
        /// </summary>
        protected virtual void DisposeUnmanaged()
        {
        }

        /// <summary>
        /// Throws a <see cref="ObjectDisposedException"/> if this instance is disposed.
        /// </summary>
        protected void ThrowIfDisposed()
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources.
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
        /// <c>false</c> to release only unmanaged resources, called from the finalizer only.</param>
        private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.isDisposed)
            {
                // If disposing managed and unmanaged resources.
                if (disposing)
                {
                    this.DisposeManaged();
                }

                this.DisposeUnmanaged();

                this.isDisposed = true;

                if (this.whenDisposedSubject != null)
                {
                    // Raise the WhenDisposed event.
                    this.whenDisposedSubject.OnNext(Unit.Default);
                    this.whenDisposedSubject.OnCompleted();
                    this.whenDisposedSubject.Dispose();
                }
            }
        }
    }
}
```

There are several interesting facets to this implementation.

1. There is a difference between disposing of managed and unmanaged resources in the disposable pattern. To facilitate this, there are two separate protected methods which can be overridden in a derived class to dispose of each of them.
2. The disposable pattern requires you to throw an `ObjectDisposedException` when you try to access a property or method after the object has been disposed. To achieve this, there is a `ThrowIfDisposed` helper method which can be added to the top of each property or method.
3. There is an `IsDisposed` property which can be useful if we don't know if the object is disposed or not.
4. Finally, there is a Reactive Extensions (Rx) observable `WhenDisposed` property. This allows us to register for the dispose event.

Here is an example of how the base class is used to dispose of both a managed and unmanaged (COM object) resources.

```cs
public class DisposableExample : Disposable
{
    private ManagedResource managedResource;
    private UnmanagedResource unmanagedResource;

    public void Foo()
    {
        this.ThrowIfDisposed();

        // Do Stuff
    }

    protected override void DisposeManaged() =>
        this.managedResource.Dispose();

    protected override void DisposeUnmanaged()
    {
        Marshal.ReleaseComObject(this.unmanagedResource);
        this.unmanagedResource = null;
    }
}
```

An example of how to dispose of an instance of the above object.

```cs
DisposableExample disposable = new DisposableExample();
disposable.WhenDisposed.Subscribe(x => Console.WriteLine("Disposed Event Fired"));
disposable.Dispose();
Console.WriteLine(disposable.IsDisposed);
```

As you can see, it looks a whole lot simpler and has some pretty cool helper functions and features. No more need to remember how to implement this complicated pattern.

## Web Mentions

[What's this?](https://en.wikipedia.org/wiki/Webmention)

### 0 Linked

### 0 Replies

## GitHub Comments

### 5 Comments

[Comment on GitHub](https://github.com/RehanSaeed/rehansaeed.github.io/issues/91)

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **Muhammad Rehan Saeed** commented on **2014-09-10 08:43:45**

I had a very interesting conversation with 'holymoo' on Reddit that I thought I'd post here.

[@HolyMoo](https://github.com/HolyMoo)  
 So, the value with implementing this `IDisposable` base class is to more effectively manage memory when it comes to working with hardware components like the gps and the compass. Now I completely agree that these object need to be disposed of when their usefulness ends.  
 I think a base class like this adds a lot of overhead for doing an operation that can be accomplished by simply using a using statement or calling dispose.  
 Maybe another way to phrase this would be, when is there a situation where you would want the viewmodel to implement `IDisposible`?

[@RehanSaeed](https://github.com/RehanSaeed)  
 Sometimes, you want disposables to exist for the lifetime of the view model. Not just things like GPS and compass but event subscriptions which should be disposed unless you like memory leaks and other things which are more likely to popup if you use WPF with COM components for example.  
 Starting with a disposable base class and building on top of that gives this ability if its needed. Its totally optional to dispose something or not. As for performance, it has almost zero impact. Adding an extra class in the inheritance hierarchy and doing a few boolean checks has a negligible performance impact.  
 I have thought if its worth it in some of my simpler WinRT projects as you have. If you don't need it, its pretty simple to remove or you can ignore it.

[@HolyMoo](https://github.com/HolyMoo)  
 I can see that. I typically try to avoid writing classes which inherit from `IDisposable` for the sake of trying to architect things in such a way to keep using statements as small as possible.

[@RehanSaeed](https://github.com/RehanSaeed)  
 Correct. But even Microsoft does it. They implement `IDisposable` and then tell you not to use it. `HttpClient` is a good example.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Thomas](https://camo.githubusercontent.com/20f1d139fa596eead0b63650b7132cb189209b34e366183b880ac14806c93879/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f38626334626363386333383264323966353563393365643763333534636536653f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/20f1d139fa596eead0b63650b7132cb189209b34e366183b880ac14806c93879/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f38626334626363386333383264323966353563393365643763333534636536653f733d393626643d6d6d26723d67) **Thomas** commented on **2017-01-11 16:43:03**

Where are you getting the Unit ans Observable types?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2017-01-12 10:49:14**

> Where are you getting the Unit ans Observable types?

From the Reactive Extensions NuGet packages.

[![tchoha](https://avatars.githubusercontent.com/u/90052922?v=4)](https://github.com/tchoha)

### [tchoha](https://github.com/tchoha)

9 November 2022 (edited 10 November 2022)

I found your article quite helpful. However I'm considering what will happen if Dispose is called concurrently. Maybe a guard with Interlocked.Exchange is needed to address such cases. Something like:

```
int _IsDisposed;
public bool IsDisposed => _IsDisposed != 0;
private void Dispose(bool disposing)
{
    bool alreadyDisposed = Interlocked.Exchange(ref _IsDisposed, 1) != 0;
    if (!alreadyDisposed)
    {
        ...
```

Please let me know your opinion on that matter?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

10 November 2022

[@tchoha](https://github.com/tchoha) Yes, you have the correct answer if you need to add thread safety for some reason. More info below:

https://stackoverflow.com/questions/8927878/what-is-the-correct-way-of-adding-thread-safety-to-an-idisposable-object

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://rehansaeed.com/#website","@type":"WebSite","description":"Software Developer at Microsoft, YouTuber, Open Source Contributor and Blogger","inLanguage":"en-GB","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/","author":{"@id":"https://rehansaeed.com/#identity"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://rehansaeed.com/?search={search_term_string}"},"query-input":"required name=search_term_string"}],"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/#webpage","@type":"WebPage","dateModified":"2014-06-13T00:00:00+00:00","datePublished":"2014-06-13T00:00:00+00:00","description":"Implementing IDisposable correctly is ridiculously hard. A Disposable base class can make it easier. Using IDisposable in Model-View-ViewModel (MVVM) really helps.","name":"Model-View-ViewModel (MVVM) - Part 2 - IDisposable","url":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/","breadcrumb":{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/#breadcrumb"},"isPartOf":{"@id":"https://rehansaeed.com/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/"]}]},{"@id":"https://rehansaeed.com/#identity","@type":"Person","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/about/","image":{"@id":"https://rehansaeed.com/#/schema/image/1"},"sameAs":["https://github.com/RehanSaeed","https://www.linkedin.com/in/muhammad-rehan-saeed","https://stackoverflow.com/users/1212017/muhammad-rehan-saeed","https://www.youtube.com/c/MuhammadRehanSaeed","https://www.twitch.tv/rehansaeeduk"]},{"@id":"https://rehansaeed.com/#publisher","@type":"Organization","logo":"https://rehansaeed.com/images/schema/Publisher-600x60.png","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com"},{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/#article","@type":"Article","dateModified":"2014-06-13T00:00:00+00:00","datePublished":"2014-06-13T00:00:00+00:00","description":"Implementing IDisposable correctly is ridiculously hard. A Disposable base class can make it easier. Using IDisposable in Model-View-ViewModel (MVVM) really helps.","headline":"Model-View-ViewModel (MVVM) - Part 2 - IDisposable","inLanguage":"en-GB","url":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/","author":{"@id":"https://rehansaeed.com/#identity"},"image":[{"@type":"ImageObject","url":"https://rehansaeed.com/images/hero/MVVM-1366x768.png","caption":"MVVM","width":"1366","height":"768"}],"isPartOf":{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/#webpage"},"keywords":[".NET","Base Class Library","BCL","C#","Design Patterns","IDisposable","Model-View-ViewModel (MVVM)","MVVM","Reactive Extensions","Rx"],"mainEntityOfPage":{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/#webpage"},"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://rehansaeed.com/","position":1},{"@type":"ListItem","name":"Model-View-ViewModel (MVVM) - Part 2 - IDisposable","item":"https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/","position":2}]},{"@id":"https://rehansaeed.com/#/schema/image/1","@type":"ImageObject","contentUrl":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png","inLanguage":"en-GB","url":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png"}]}
```

## Sitemap

See the full [sitemap](https://rehansaeed.com/sitemap.md) for all pages.
