0

When using Reactive Extensions it is common to find methods that return IDisposable. It is very rare that these IDisposables can be ignored and if done so will cause memory leaks and bizarre program operations.

There is CA1806 - Do not ignore method results but that is too general for a programming language like C#. I would just like to mark unprocessed IDisposables as a fatal error.

I will often write code like this in the constructor of a custom user control

this.LoadUnloadHandler
    ((CompositeDisposable c) =>
    {

        this
            .Events()
            .GotFocus
            .Subscribe
            (e =>
            {
                if (EntitySelectorManager == null)
                    return;
                EntitySelectorManager.ActiveSelectorControl = this;
            })
            .DisposeWith(c);

        this
            .WhenAnyValue(p => p.Selection)
            .WhereNotNull()
            .Subscribe(selection => ItemsSource = MakeListText(selection));
        //////////////////////////////////////////////////
        // OOOOPS I forgot to add a DisposeWith(c) here..
        // The subscription will leak
        //////////////////////////////////////////////////


        // Handle the case of an empty list box not
        // being able to get focus.
        this.Events().PreviewMouseDown
            .Subscribe
            (e =>
            {
                if(Items.Count==0)
                    Focus();
            })
            .DisposeWith(c);

        // Remove the list selection on lost focus.
        this.Events().LostFocus
            .Subscribe
            (e => SelectedIndex = -1)
            .DisposeWith(c);


    });

where DisposeWith is just an extension method to add an IDisposable to a CompositeDisposable. All generated IDisposables should be added but the compiler at the moment does not check this for me.

So to be specific. Is there a built in Roslyn Analyzer / a Resharper Analyzer or an open source analyzer than can catch this and fail my build or do I have to write one from scratch?

bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217
  • i'm not sure about automated checks but the general way you should use an IDisposable is inside a using statement, the only time you shouldn't is when the disposables lifecycle is larger than the current contexts lifespan which is very rare and probably indicative of a mistake on the programmers part – MikeT Mar 01 '17 at 13:53
  • No. You are thinking about lexical scoping of IDisposable. It is not always the correct pattern. I generate a load of IDisposables when a user control is displayed and when it is removed from the visual tree / hidden I need to dispose them to avoid resource leaks. The scoping is time based not lexical. – bradgonesurfing Mar 01 '17 at 13:56

0 Answers0