Using "using" - Don't get stuck loading!
2026-06-28
Tags: .NET
Managing loading states is surprisingly difficult. It requires a constant awareness of the potential for a method to exit early, and the discipline to remember to un-set your loading state when you've finished doing work.
Consider, for example, this method, which will leave its class stuck in a loading state forever if it throws:
public void Init()
{
IsLoading = true;
DoWork();
IsLoading = false;
}
Or this one, where the developer forgot to reset the value (this is a lot more of a problem in complex methods with multiple return paths):
public void Init()
{
IsLoading = true;
DoWork();
// Forgot IsLoading = false!
}
The safe pattern here, shown below, introduces 8 lines of boilerplate and an ugly level of indentation. It's robust, but sacrifices some readability, and writing it gets old quickly.
public void Init()
{
IsLoading = true;
try
{
DoWork();
}
finally
{
IsLoading = false;
}
}
So, let me run this pattern by you. For any class that needs loading behaviour, make sure it inherits LoadingBase:
internal abstract class LoadingBase
{
public bool IsLoading { get; private set; }
protected IDisposable UseLoading() =>
new LoadingDisposable(this);
private class LoadingDisposable : IDisposable
{
private readonly LoadingBase _lb;
public LoadingDisposable(LoadingBase lb)
{
_lb = lb;
_lb.IsLoading = true;
}
public void Dispose()
{
_lb.IsLoading = false;
}
}
}
This lets us use the following pattern:
public void Init()
{
using var loading = UseLoading();
DoWork();
}
Which is lowered to:
public void Init()
{
IDisposable loading = UseLoading();
try
{
DoWork();
}
finally
{
loading.Dispose();
}
}
This ensures that IsLoading is set to false no matter when or how the method exits, with only one line. Far less boilerplate than the explicit try/finally pattern!
The one drawback here is that you can't use discard assignment in a using statement. If you do, _ becomes a variable of type IDisposable, much as if it were used as the name of a parameter.
