Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Generic Async Factory

0.00/5 (No votes)
24 Nov 2006 1  
A Generic Extensible Async Factory

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()
 {
     //Call the BeginCreate of the factory with a callback.
     appFactory.BeginCreate(new AsyncCallback(this.AppCreateCallback), true);
 }
 
 public void AppCreateCallback(IAsyncResult result) 
 {
     //Call the EndCreate to get the object created by the factory.
     this.wordApp = appFactory.EndCreate(result);

     //start using the wordApp instance.
     //this.wordApp.Documents.Open(....
 }

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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here