Introduction
Factories are used for creating objects. Different objects would have different creational logic. There are instances where the object creation might consume time and you may want to move the logic onto a non-blocking thread to keep the application responsive. The AsyncFactory
is a step towards that. You can have different factory implementations, without worrying about the asynchronous execution logic.
The AsyncFactory
The AsyncFactory
is a Generic class which can be sub classed for any factory implementation, that needs to executed asynchronously. The AysncFactory
is an Abstract Generic class with a single protected abstract Create
method. The method accepts a type parameter <P>
and returns a type <T>
. This method needs to be overridden in the subclass with specific implementation of your interest with the appropriate parameter and return types.
public abstract class AysncFactory<TReturn, TParam>
{
protected abstract TReturn Create(TParam createParams);
}
Internally the AysncFactory
uses the age old .NET ThreadPool and queues the creation logic on a non-blocking thread. It has a BeginCreate
and an EndCreate
implementation, which eventually gets exposed to the clients. They follow the conventional BeginXXX
and EndXXX
signature and implementation.
public IAsyncResult BeginCreate(AsyncCallback callback, TParam createParams);
public TReturn EndCreate(IAsyncResult asyncResult);
There's an CreateAsyncResult
class that implements IAsyncResult
. It contains a private ManualResetEvent
member to block the client when the EndCreate
is called, till the creation logic is completed. The BeginCreate
queues an internal AsyncCreate
method which actually invokes the overridden Create
method. Once the Create
method completes, the AsyncCreate
sets the flag on the WaitHandle
, invokes the callback and returns. The EndCreate
calls the WaitOne
on the WaitHandle
, which blocks till the Create
function completes and then the set on the WaitHandle
is called to signal all the blocked threads.
The clients call the BeginCreate
with the callback and the parameters that need to be passed to the create
method. The BeginCreate
returns an IAsyncResult
, which is needed to be passed to the EndCreate
to trigger the completion. The EndCreate
blocks until the creation is completed and returns the created object.
Sample Implementation
WinWordApplicationFactory
is a factory class which creates instances of WinWord Application object. The Create
method takes a boolean value to turn on/off the visible property, and returns an instance of ApplicationClass
:
public class WinWordApplicationFactory : AsyncFactory<MSWordApplication, bool>
{
protected override MSWordApplication Create(bool isVisible)
{
object oMissing = System.Reflection.Missing.Value;
MSWordApplication msWord = new MSWordApplication();
msWord.Visible = isVisible;
return msWord;
}
}
Client
private ApplicationClass wordApp;
private WinWordApplicationFactory appFactory;
public WinWordFactoryClient()
{
this.appFactory = new WinWordApplicationFactory();
this.CreateWordInstance();
}
private void CreateWordInstance()
{
appFactory.BeginCreate(new AsyncCallback(this.AppCreateCallback), true);
}
public void AppCreateCallback(IAsyncResult result)
{
this.wordApp = appFactory.EndCreate(result);
}
Conclusion
Generally Factory
classes are singleton. I'm on the way to implementing the same. Till then, happy coding!
History
- 24th November, 2006: Initial post