Context manager for SuspendLayout I've found a few places where control updates take longer than the redraw cycle.

I started off surrounding them with Suspend and ResumeLayout: 

container.SuspendLayout(); 
updateControls(); 
container.ResumeLayout(true);


After doing that a few times, I realized it could be refactored into a context:

/// &lt;summary&gt;
/// Context manager to suspend and resume layout engine while performing 
/// updates that take longer than a refresh cycle
/// &lt;/summary&gt;
/// &lt;example&gt;using (new SuspendLayoutContext(container)
///     DoSlowUpdate(container.Controls);&lt;/example&gt;
class SuspendLayoutContext : IDisposable
{
    private readonly Control _control;
    private readonly bool _performLayoutAfter;

    /// &lt;summary&gt;
    /// Constructs the context manager to suspend and resume layout.
    /// &lt;/summary&gt;
    /// &lt;param name="container"&gt;&lt;/param&gt;
    /// &lt;param name="performLayout"&gt;&lt;/param&gt;
    public SuspendLayoutContext(Control container, bool performLayoutAfter=true)
    {
        _control = container;
        _performLayoutAfter = performLayoutAfter;
        _control.SuspendLayout();
    }

    /// &lt;summary&gt;Calls ResumeLayout on the container.&lt;/summary&gt;
    /// &lt;remarks&gt;If you call this manually, you are probably using this class wrong.&lt;/remarks&gt;
    public void Dispose()
    {
        _control.ResumeLayout(_performLayoutAfter);
    }
}


Then, the above code would look like

using (new SuspendLayoutContext(container))
{
    updateControls(); 
}


I then decided I didn't like having to call the constructor every time, so I created an extension method (/// comments elided for brevity):

static class ControlExtensions
{
    public static SuspendLayoutContext SuspendLayoutContext(this Control container, bool performLayoutAfter=true)
    {
        return new SuspendLayoutContext(container, performLayoutAfter);
    }
}


The example then looks like

using (container.SuspendLayoutContext())
{
    updateControls(); 
}


Questions


Is there any reason not to use an IDisposable context here?  I'm more familiar with python, where I wouldn't hesitate to create new context managers - but the method name Dispose() raises red flags. (In python, it's __exit__.)
I debated between the extension method on Control and a static method on SuspendLayoutContext:

public static SuspendLayoutContext For(Control container, bool performLayoutAfter=true)
{
    return new SuspendLayoutContext(container, performLayoutAfter)
}


While I'm a big fan of fluent interfaces, the extension method felt cleaner.  What alternatives might be better?
I always miss something when I do this, what is it this time?
I think there is nothing wrong with using IDisposable whenever a class requires some sort of clean-up. It might have been originally designed to release unmanaged resources, but it is definitely no longer the case. Nowadays people use IDisposable to do all sort of things: unsubscribe from events, release pooled objects, flush buffers... this list goes on and on.



I also would prefer extension method over other options. It looks cleaner IMHO. What I don't like is the Context word. Not only because the method name should be a verb, but also because its somewhat misleading. I think a lot of people will assume that ...Context class is the class that implements context object (anti-)pattern. But your class doesn't. For example, class LayoutSuspender both sounds funny and describes what the class does. Win-win.



The thing you should be careful about is using this class with nested methods. For example, this:

public void UpdateAllControls()
{
    using (container.SuspendLayoutContext())
    {
        UpdateControlA(); 
        UpdateControlB(); 
    }
} 

public void UpdateControlA()
{
    using (container.SuspendLayoutContext())
    {
        UpdateControlA(); 
    }
} 


won't work as you want it to. So eventually you might want to implement some sort of reference counting.