XAML Playground
about XAML and other Amenities

A base class for threaded Application Services

2011-02-21T23:26:16+01:00 by Andrea Boschin

Continuing of my series about IApplicationServices I would like to propose a base class I've created to easily develop Application Services that runs a thread. There are lot of cases when you implement IApplicationService to run a parallel task that accomplish some kind of background tasks. I've collected all the redundant code inside a class I called ThreadedService. Extending this class you have a thread automatically started and stopped according with the application lifetime. Here is the class:

public abstract class ThreadedService : IDisposable, IApplicationService, IApplicationLifetimeAware
{
    /// <summary>
    /// Gets or sets the exit event.
    /// </summary>
    /// <value>The exit event.</value>
    private ManualResetEvent ExitEvent { get; set; }
 
    /// <summary>
    /// Gets or sets the wait handles.
    /// </summary>
    /// <value>The wait handles.</value>
    protected WaitHandle[] ExitHandles { get; set; }
 
    /// <summary>
    /// Initializes a new instance of the <see cref="ThreadedObject"/> class.
    /// </summary>
    public ThreadedService()
    {
        this.ExitEvent = new ManualResetEvent(false);
        this.ExitHandles = new WaitHandle[] { this.ExitEvent };
    }
 
    /// <summary>
    /// The main thread body
    /// </summary>
    protected abstract void ThreadProc();
 
    #region IDisposable Members
 
    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public virtual void Dispose()
    {
        this.StopService();
    }
 
    #endregion
 
    #region IApplicationLifetimeAware
 
    public virtual void Starting()
    { }
 
    public virtual void Started()
    {
        ThreadStart listenThreadStart = new ThreadStart(ThreadProc);
        Thread thread = new Thread(listenThreadStart);
        thread.Start();
    }
 
    public virtual void Exiting()
    {
        this.ExitEvent.Set();
    }
 
    public virtual void Exited()
    { }
 
    #endregion
 
    #region IApplicationService
 
    public virtual void StartService(ApplicationServiceContext context)
    { }
 
    public virtual void StopService()
    { }
 
    #endregion
}

As already said the class is able to manage the background thread automatically but require a little level of collaboration when you develop the body of the thread. Infact after overriding the ThreadProc method you have to listen for the ExitEvent to be raised. When this event is set you have to exit from the service as soon as possible.

Saying we have to poll the newtork once every minute you can implement the ThreadProc the way I show it in the figure.

protected override void ThreadProc()
{
    this.Update();
 
    while (WaitHandle.WaitAny(this.ExitHandles, 5000) == WaitHandle.WaitTimeout)
        this.Update();
}

The procedure wait for the ExitEvent for a timeout. During this time the runtime is able to do something else but once the event is set the process is immediately exited. Something very simple but effective.

Categories:   TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Inject ApplicationServices with MEF reloaded: supporting recomposition

2011-02-17T16:35:03+01:00 by Andrea Boschin

In my I've presented a simple solution that allows people to adds instances of ApplicationServices, without the need of adding the markup to the App.xaml file. The solution was interesting as a demonstration of how MEF works, but after some tests and some feedbacks I had I realized it is not applicable in a real world solution because of a subtle problem.

The problem is given by a conflict in the lifetime of the application between the Application_Start event and the StartService method. If you put the code to inizialize the CompositionContainer inside of the Application_Start event you may get an error stating that the composition has already initialized, just because when the StartService method call the CompositionInitializer method, to compose the services, the container is implicitly initialized. Unfortunately the Application_Start method is called after the StartService so here is the reason of the error you get.

For a long while I've thinked this may remain only a beautiful example because I do not discovered a valid solution, but today I convinced myself that a correction to this problem is possible and that it also add the ability of supporting recomposition to the HostService. As far as I know there is not any concern in calling the methods of the service with a delay respect the runtime raises the corrisponding method, almost until the method is not one of the Exit flavour. During the exit we have to free resources, stop threads, and so on and it is important to make these actions as soon as possible to let the runtime able to close the application faster. But the initialization phase may start in a later time, with the sole constraint that the sequence of the methods should be the same.

So this morning I've worked in this direction and in the following box you can see the resulting solution:

   1: public class HostService : IApplicationService, IApplicationLifetimeAware, IPartImportsSatisfiedNotification
   2: {
   3:     /// <summary>
   4:     /// Gets or sets the context.
   5:     /// </summary>
   6:     /// <value>The context.</value>
   7:     public ApplicationServiceContext Context { get; set; }
   8:     /// <summary>
   9:     /// Gets or sets the current.
  10:     /// </summary>
  11:     /// <value>The current.</value>
  12:     public static HostService Current { get; private set; }
  13:  
  14:     /// <summary>
  15:     /// Gets or sets the initialized.
  16:     /// </summary>
  17:     /// <value>The initialized.</value>
  18:     private List<IApplicationService> Initialized { get; set; }
  19:  
  20:     /// <summary>
  21:     /// Gets or sets the services.
  22:     /// </summary>
  23:     /// <value>The services.</value>
  24:     [ImportMany(AllowRecomposition = true, RequiredCreationPolicy = CreationPolicy.Shared)]
  25:     public List<IApplicationService> Services { get; set; }
  26:  
  27:     /// <summary>
  28:     /// Initializes a new instance of the <see cref="HostService"/> class.
  29:     /// </summary>
  30:     public HostService()
  31:     {
  32:         if (HostService.Current != null)
  33:             throw new InvalidOperationException("Service already exists");
  34:  
  35:         HostService.Current = this;
  36:         this.Initialized = new List<IApplicationService>();
  37:     }
  38:  
  39:     /// <summary>
  40:     /// Called by an application immediately after the <see cref="E:System.Windows.Application.Exit"/> event occurs.
  41:     /// </summary>
  42:     public void Exited()
  43:     {
  44:         foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
  45:             service.Exited();
  46:     }
  47:  
  48:     /// <summary>
  49:     /// Called by an application immediately before the <see cref="E:System.Windows.Application.Exit"/> event occurs.
  50:     /// </summary>
  51:     public void Exiting()
  52:     {
  53:         foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
  54:             service.Exiting();
  55:     }
  56:  
  57:     /// <summary>
  58:     /// Called by an application immediately after the <see cref="E:System.Windows.Application.Startup"/> event occurs.
  59:     /// </summary>
  60:     public void Started()
  61:     {
  62:         CompositionInitializer.SatisfyImports(this);
  63:     }
  64:  
  65:     /// <summary>
  66:     /// Called by an application immediately before the <see cref="E:System.Windows.Application.Startup"/> event occurs.
  67:     /// </summary>
  68:     public void Starting()
  69:     {
  70:     }
  71:  
  72:     /// <summary>
  73:     /// Called by an application in order to initialize the application extension service.
  74:     /// </summary>
  75:     /// <param name="context">Provides information about the application state.</param>
  76:     public void StartService(ApplicationServiceContext context)
  77:     {
  78:         this.Context = context;
  79:     }
  80:  
  81:     /// <summary>
  82:     /// Called by an application in order to stop the application extension service.
  83:     /// </summary>
  84:     public void StopService()
  85:     {
  86:         foreach (IApplicationService service in this.Services)
  87:             service.StopService();
  88:     }
  89:  
  90:     /// <summary>
  91:     /// Called when a part's imports have been satisfied and it is safe to use.
  92:     /// </summary>
  93:     public void OnImportsSatisfied()
  94:     {
  95:         // buffer for services that raises exception during initialization
  96:         List<IApplicationService> errors = new List<IApplicationService>();
  97:  
  98:         // call StartService
  99:         foreach (IApplicationService service in this.Services.OfType<IApplicationService>().Except(this.Initialized))
 100:         {
 101:             try
 102:             {
 103:                 service.StartService(this.Context);
 104:             }
 105:             catch
 106:             {
 107:                 errors.Add(service);
 108:             }
 109:         }
 110:  
 111:         // call Starting
 112:         foreach (IApplicationLifetimeAware service in 
 113:             this.Services.OfType<IApplicationLifetimeAware>()
 114:             .Except(this.Initialized.OfType<IApplicationLifetimeAware>())
 115:             .Except(errors.OfType<IApplicationLifetimeAware>()))
 116:         {
 117:             try
 118:             {
 119:                 service.Starting();
 120:             }
 121:             catch
 122:             {
 123:                 errors.Add((IApplicationService)service);
 124:             }
 125:         }
 126:  
 127:         // call Started
 128:         foreach (IApplicationLifetimeAware service in 
 129:             this.Services.OfType<IApplicationLifetimeAware>()
 130:             .Except(this.Initialized.OfType<IApplicationLifetimeAware>())
 131:             .Except(errors.OfType<IApplicationLifetimeAware>()))
 132:         {
 133:             try
 134:             {
 135:                 service.Started();
 136:             }
 137:             catch
 138:             {
 139:                 errors.Add((IApplicationService)service);
 140:             }
 141:         }
 142:  
 143:         // register ad Initialized to avoid duplicated initialization in case of recomposition
 144:         foreach (IApplicationService service in 
 145:             this.Services.OfType<IApplicationService>()
 146:             .Except(this.Initialized)
 147:             .Except(errors))
 148:             this.Initialized.Add(service);
 149:  
 150:         // remove services that raised exceptions
 151:         foreach (IApplicationService service in errors)
 152:             this.Services.Remove(service);
 153:     }
 154: }

As you can see the structure of the service remains the same, and also the management of the Exit, Exited and StopService is not changed. The very important change is in the Started method, that is called after the Application_Start event. In this method I only perform the composition. Then, in the OnImportsSatisfied method I start a sequence to emulate the startup of the service, repeating the flow that an ApplicationService usually follow during it initialization. I've also added some code to manage exceptions raised during the initialization. In these cases the services that raised the errors do not follow the remaining parts of the initialization and finally are removed from the Services collection.

In the service I maintain a collection of Initialized services because if the recomposition happen I must not repeat the inizialization of services that were already initialized previously. This is also the reason that make me asking a Shared CreationPolicy, because when the composition container compose the Services property does not have to create new instances but only have to add the new services coming from the recomposition.

I hope this solution to be more reliable than the previous one. As usual I will be glad to have feedback from you to continue improving the code..

Categories:   TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Singleton ApplicationServices explained

2011-02-17T09:44:39+01:00 by Andrea Boschin

My has opened to some unexpected questions about what may seems a strangeness in my code. I was surprised about this questions, just because I believed it was a known pattern, so I decided to give an explanation to ones that does not know the reason I wrote some lines of code in the constructor

   1: public class SampleService : IApplicationService
   2: {
   3:     public static SampleService Current { get; private set; }
   4:  
   5:     /// <summary>
   6:     /// Initializes a new instance of the <see cref="ServiceHost"/> class.
   7:     /// </summary>
   8:     public SampleService()
   9:     {
  10:         if (SampleService.Current != null)
  11:             throw new InvalidOperationException("Service already exists");
  12:  
  13:         SampleService.Current = this;
  14:     }
  15:  
  16:     // omissis...
  17: }

The problem here is that sometimes it is not useful (and sometimes it is definitely bad) to have more than an instance of an ApplicationService running behind the scenes. Given that none can limit the number of instances in the ApplicationLifetimeObjects collection I use a pattern to avoid this problem.

First of all I expose a static property "Current". This property is useful to interact with the running service from any part of the code. Since after the beta there is not an indexer to access the running service this is the most common pattern used for this purpose.

Then in the constructor I check the property "Current" to be null. If I found a value it means someone is trying to put two instances of the service in the markup, so I raise an exception stating that only one instance is allowed. In the case "Current" is empty I save myself to this property using "this".

So nothing is wrong in my previous example. Only few lines of code to implement a Singleton pattern for IApplicationService, with a tecnique that is widely used also inside the framework classes.

Categories:   TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Inject Application Services using MEF

2011-02-06T22:33:47+01:00 by codeblock

For an example I'm writing for my next presentation at the end of February, I’m trying to build an application skeleton that have lot of extensibility points and my goal is to make almost everything pluggable. An interesting thing I did today is to inject in the application a number of ApplicationServices. The application services are an useful tool to have application-wide services available during the entire lifetime, and they are very easy to create and install. First of all you have to implement the IApplicationService interface and if you want a more detailed control on application lifecycle you can also implement the IApplicationLifetimeAware interface. These interfaces give you a number of methods that notify when the application is started of stopped. Here is an example of a service and its installation:

   1: public class SampleService : IApplicationService
   2: {
   3:     public static SampleService Current { get; private set; }
   4:  
   5:     /// <summary>
   6:     /// Initializes a new instance of the <see cref="ServiceHost"/> class.
   7:     /// </summary>
   8:     public SampleService()
   9:     {
  10:         if (SampleService.Current != null)
  11:             throw new InvalidOperationException("Service already exists");
  12:  
  13:         SampleService.Current = this;
  14:     }
  15:  
  16:     /// <summary>
  17:     /// Called by an application in order to initialize the application extension service.
  18:     /// </summary>
  19:     /// <param name="context">Provides information about the application state.</param>
  20:     public void StartService(ApplicationServiceContext context)
  21:     {
  22:         // initialize here the service
  23:     }
  24:  
  25:     /// <summary>
  26:     /// Called by an application in order to stop the application extension service.
  27:     /// </summary>
  28:     public void StopService()
  29:     {
  30:         // release resources here
  31:     }
  32: }
  33:  
  34: // -----------
  35:  
  36: <Application.ApplicationLifetimeObjects>
  37:     <local:SampleService />
  38: </Application.ApplicationLifetimeObjects>

Today I've asked myself how can I inject an application service with MEF. If I have many modules I plug to my skeleton, let say they are customization for different customers, I suppose I can also have one or more application services injected by these modules for the purpose of the customization. To solve this pluggability problem I’ve created a simple HostService that implement both IApplicationService and IApplicationLifetimeAware, then I added a property, imported with MEF, that is a collection of IApplicationService. So when I load the ApplicationService in the App.xaml the constructor perform the Composition and I have a bunch of services loaded into the host service.

   1: public class HostService : IApplicationService, IApplicationLifetimeAware
   2: {
   3:     public static HostService Current { get; private set; }
   4:  
   5:     /// <summary>
   6:     /// Gets or sets the services.
   7:     /// </summary>
   8:     /// <value>The services.</value>
   9:     [ImportMany]
  10:     public IEnumerable<IApplicationService> Services { get; set; }
  11:  
  12:     /// <summary>
  13:     /// Initializes a new instance of the <see cref="ServiceHost"/> class.
  14:     /// </summary>
  15:     public HostService()
  16:     {
  17:         if (HostService.Current != null)
  18:             throw new InvalidOperationException("Service already exists");
  19:  
  20:         HostService.Current = this;
  21:         CompositionInitializer.SatisfyImports(this);
  22:     }
  23:  
  24:     /// <summary>
  25:     /// Called by an application immediately after the <see cref="E:System.Windows.Application.Exit"/> event occurs.
  26:     /// </summary>
  27:     public void Exited()
  28:     {
  29:         foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
  30:             service.Exited();
  31:     }
  32:  
  33:     /// <summary>
  34:     /// Called by an application immediately before the <see cref="E:System.Windows.Application.Exit"/> event occurs.
  35:     /// </summary>
  36:     public void Exiting()
  37:     {
  38:         foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
  39:             service.Exiting();
  40:     }
  41:  
  42:     /// <summary>
  43:     /// Called by an application immediately after the <see cref="E:System.Windows.Application.Startup"/> event occurs.
  44:     /// </summary>
  45:     public void Started()
  46:     {
  47:         foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
  48:             service.Started();
  49:     }
  50:  
  51:     /// <summary>
  52:     /// Called by an application immediately before the <see cref="E:System.Windows.Application.Startup"/> event occurs.
  53:     /// </summary>
  54:     public void Starting()
  55:     {
  56:         foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
  57:             service.Starting();
  58:     }
  59:  
  60:     /// <summary>
  61:     /// Called by an application in order to initialize the application extension service.
  62:     /// </summary>
  63:     /// <param name="context">Provides information about the application state.</param>
  64:     public void StartService(ApplicationServiceContext context)
  65:     {
  66:         foreach (IApplicationService service in this.Services)
  67:             service.StartService(context);
  68:     }
  69:  
  70:     /// <summary>
  71:     /// Called by an application in order to stop the application extension service.
  72:     /// </summary>
  73:     public void StopService()
  74:     {
  75:         foreach (IApplicationService service in this.Services)
  76:             service.StopService();
  77:     }
  78: }

As you can see in the code, for every method exposed by the interfaces I make a loop and call the corresponding method on each service. The services have to be exported ad IApplicationService, but if they implements also the other interface the host call the relative methods. To export a service you can simple decorate it with an Export attribute.

   1: [Export(typeof(IApplicationService))]
   2: public SampleService : IApplicationService
   3: {
   4:     // implement the service
   5: }

Once installed, this very simple service let you easily inject new services without the need of recompile the software. Simply add the assembly where it resides to the catalog and the services will be installed seamless.

Magic…

Categories:   TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Windows Phone 7 series continues...

2011-02-02T16:46:26+01:00 by Andrea Boschin

SilverlightShowAbout two weeks ago I started a series of articles about the Windows Phone 7 hosted by the well knows site SilverlightShow. In the very first rows of the opening article I wrote: "Starting with this article we will follow a path to discover one by one all the aspects of this device". The intent of the series is infact to give a walkthrough, starting from scratch, about the brand new device that is born in the previous months.

Now we are at the third number of the series and after having explained the most simple but not always obvious details of the UI, now it is time to go forward to explore the navigation paradigm that permeates you phone. This number will introduce to the problems of application lyfecycle and tombstoning that will be the argument of the fourth part I'm about to write.

If you have lost the previous number here is the links:

Windows Phone 7 Part #1: Getting Started

Windows Phone 7 Part #2: Your first app

As usual, if you have feedback or requests, you have only to write me or to Silverlightshow and we will fast answer to your needs.

Have a good reading

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed