Initializing Components in the Background
The project I’m currently working on relies a lot on SOA, so we’ve got a bunch of classes that represent modularized services. Some of these services need to load some information from a database or other external sources, and rather than tying up the user interface thread, we wanted to do this initialization in the background. To solve this problem, I created an abstract base type for the services called BackgroundInitObject:
public abstract class BackgroundInitObject : IDisposable
{
private ManualResetEvent _initEvent;
private bool _isInitialized;
public bool IsInitialized
{
get { return _isInitialized; }
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Ensure no threads are blocked.
if (disposing && (_initEvent != null))
_initEvent.Set();
}
~BackgroundInitService()
{
Dispose(false);
}
protected BackgroundInitService()
{
_initEvent = new ManualResetEvent(false);
}
public void BeginInit()
{
ThreadPool.QueueUserWorkItem(delegate
{
// Initialize the service.
Init();
// Unblock any waiting threads.
_initEvent.Set();
// Set the initialized flag.
_isInitialized = true;
});
}
protected void WaitForInit()
{
// Block the calling thread until the service is initialized.
_initEvent.WaitOne();
}
protected abstract void Init();
}
As you can see, this type uses one of the ThreadPool threads to execute the class’s initialization logic. Now, to create a class that initializes itself in the background, extend BackgroundInitObject and put your initialization logic in an implementation of the the abstract Init() method. Then, in any of your class’s public methods, be sure to start them with a call to WaitForInit(). This way, any threads that try to use the class will be blocked until it’s initialized.
For example, here’s a simple service that uses the pattern:
public class UserPreferenceService : BackgroundInitObject
{
private Dictionary<string, string> _preferences;
public string GetPreference(string key)
{
WaitForInit();
return _preferences.ContainsKey(key) ? _preferences[key] : null;
}
protected override void Init()
{
// Load user's preferences from a database, for example...
}
}
The first time code that consumes the UserPreferenceService calls the GetPreference() method, if the service is still initializing, the thread will block. Once the service is initialized, calls to WaitForInit() will not block, and the service will operate as normal. You can also check to see if the service is initialized by looking at the IsInitialized property, but it’s really just for informational purposes.
One question you might be asking is, why is WaitForInit() protected and not public? The intent of this is that any thread-locking that happens should be encapsulated inside the type, and not leak into the consuming client code. If you have a compelling reason to do so, you could make it public without interfering with the rest of the pattern.


