Friday, 12 April 2013

Planificateur de taches en .NET

Planifier un "background task" est une opération fréquente dans la gestion de notre système d'informations.
Ex : 
- exécuter une action chaque jour à minuit pour une application on-premise
- faire un état statistique à 2:00 am pour une application hebergée dans le cloud Windows azure.

Plusieurs solution sont à notre disposition , entre autre :
- le Windows Task Scheduler  à l'intérieur d'un worker role
- l'utilisation de bibliothèque spécialisée comme Quartz.net

Vous pouvez voir Quartz.net ici
https://github.com/quartznet/
http://quartznet.sourceforge.net/





Caching in Windows Azure

Windows azure offers two main caching mechanims :
- Windows Azure Shared Caching
- Windows Azure Caching



Tuesday, 15 January 2013

How to control the state of several objects ( bitwise operator, flag ), French version

Dans ce post, j'essaye d'apporter une solution générique au problème de gestion des statuts possibles d'un objet.
Ex : Si une barre de menus possède plusieurs boutons (1 à N), on veut qu'à un instant t, on puisse commander facilement lesquels de ces N boutons sont visibles et lesquels sont invisibles.
Beaucoup de cas sont analogues à cette problématique.


1-Pour ces N objets , créons un Enum ( ayant N valeurs possibles ):
    [Flags]
    public enum Status
    {
        Status1 = 1,
        Status2 = 2,
        Status4 = 4,
        Status8 = 8    }

Ici j'ai pris le cas de N = 4, la solution reste valable par récurrence.
Notez que les valeurs ne sont pas prises au hasard. (1,2,4,8....) est une suite géometrique de raison 2, le premier élément étant Math.Pow(2,0) = 1.
L'attribut [Flags] permet de faire des opérations "Binaire" sur  ces valeurs ( AND, OR, NOT,...).

2-Sur les N objets, utiliser le pattern "Decorateur" pour décorer ces objets avec une propriété supplémentaire permettant de stocker le statut associé à l'objet.
Pour simplifier , je vais simplement ajouter directement cette propriété directement à l'objet.

    public class Element
    {  

        //propriete standart
        public int Id { get; set; }   
        
        //propriétés supplémentaires
        public Status Status { get; set; }        //permet d'attribuer un statut
à l'objet
          public bool ToBeDisplay { get; set; }    //état de l'objet
à l'instant T
    }

3- Sur les N objets, associez un status sur chaque objet ( relation One-To-One )

            Element e1 = new Element() { Id = 1,  Status = Status.Status1 };
            Element e2 = new Element() { Id = 2,  Status = Status.Status2 };
            Element e4 = new Element() { Id = 4,   Status = Status.Status4 };
            Element e8 = new Element() { Id = 8,  Status = Status.Status8 };


4- Je regroupe ensuite l'objet dans une liste
            List<Element> elements = new List<Element>();
            elements.Add(e1);
            elements.Add(e2);
            elements.Add(e4);
            elements.Add(e8); 


5- Voici la fonction Configure qui va permettre de positionner la valeur de la propriété ToBeDisplay en fonction d'un flag entré en paramètre :

        private static List<Element>  Configure(List<Element> elts,int flag)
        {
            Status f = (Status)(Enum.Parse(typeof(Status),flag.ToString()));           
            foreach (var item in elts)
            {
                bool isToBeDisplayed = false;
                isToBeDisplayed = (item.Status & f ) == item.Status;
                item.ToBeDisplay = isToBeDisplayed;
            }
            return elts;
        }


-flag : variable de type int que l'on va caster en Status afin de pouvoir faire une opération binaire sur cette variable.
-Sur chaque élément, positionnez la propriété isToBeDisplayed .
- la ligne   isToBeDisplayed = (item.Status & f ) == item.Status; permet de jongler sur le champ Status courant de l'objet et le flag.

 Les valeurs de flag qui permettent de faire les combinaisons possibles sont sur l'intervalle: [1,Math.Pow(2,N)-1]

Dans notre cas N = 4, les valeurs de Flag intéressantes sont : 1,2,3,4,5,...15



Voici le programme complet :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    [Flags]
    public enum Status
    {       
        Status1 = 1,
        Status2 = 2,
        Status4 = 4,
        Status8 = 8,
    }

    public class Element
    {       
        public Status Status { get; set; }
        public int Id { get; set; }
        public bool ToBeDisplay { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {         
            Element e1 = new Element() { Id = 1,  Status = Status.Status1 };
            Element e2 = new Element() { Id = 2, Status = Status.Status2 };
            Element e4 = new Element() { Id = 4, Status = Status.Status4 };
            Element e8 = new Element() { Id = 8, Status = Status.Status8 };
            List<Element> elements = new List<Element>();        
            elements.Add(e1);
            elements.Add(e2);
            elements.Add(e4);
            elements.Add(e8);


            var r = Configure(elements, 7);
            foreach (var item in r)
            {
                if (item.ToBeDisplay)
                {
                    Console.WriteLine(item.Id);
                }
            }
            Console.ReadLine();
        }
        private static List<Element>  Configure(List<Element> elts,int flag)
        {
            Status f = (Status)(Enum.Parse(typeof(Status),flag.ToString()));  

            Console.WriteLine("status  =  " + f);         
            foreach (var item in elts)
            {
                bool isToBeDisplayed = false;
                isToBeDisplayed = (item.Status & f ) == item.Status;
                item.ToBeDisplay = isToBeDisplayed;
            }
            return elts;
        }
    }
}

 

Saturday, 22 December 2012

A read lock may not be acquired with the write lock, Error retrieving values from ObjectStateEntry. See inner exception for details. held in this mode.

Today , i've got this error when trying to insert record in new database.
I'm using entity framework 4.1, code first approach.

A read lock may not be acquired with the write lock,
Error retrieving values from ObjectStateEntry. See inner exception for details.

At first glance, i've thought that there's a current transaction that locks the access on the table when trying to insert a new record. So i check all actives transactions but any of them get a lock on my table.
As I use a transactionscope during the insert operation, i've removed them but the issue still not resolved.

Stop, I decided to go in deeper in the error message , that was the first thing that I had to do....

Take a close look on the InnerException.InnerException object.


Everything becomes clear now. there a violation of constraint that entity framework has detected and it raises an error when constraint has been violated.
Once those constraint have been updated, the problem is resolved !!!


Wednesday, 19 December 2012

My old vw combi split bus


NHibernate tunning

 private static ISessionFactory CreateSessionFactory1()
        {
            return Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("Sql2008")))
                //.Cache(c=>c.UseSecondLevelCache().ProviderClass(typeof(NHibernate.Caches.SysCache.SysCacheProvider).AssemblyQualifiedName))               
                //.Cache(c => c.UseQueryCache().ProviderClass(typeof(NHibernate.Caches.SysCache.SysCacheProvider).AssemblyQualifiedName))                               
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>())
                .BuildConfiguration()

            #region cache configuration
                .SetProperty(NHibernate.Cfg.Environment.UseSecondLevelCache, "true")
                .SetProperty(NHibernate.Cfg.Environment.UseQueryCache, "true")
                .Cache(c =>
                {
                    c.Provider<NHibernate.Caches.SysCache.SysCacheProvider>();
                    //    c.DefaultExpiration = 1;
                })
            #endregion
            #region configure cache on Movies Entity
            .EntityCache<Movies>(c =>
            {
                c.Strategy = EntityCacheUsage.ReadWrite;
                c.RegionName = "Region1";
            })
                        #endregion
            .BuildSessionFactory();
        }
      

   using (var session = sessionFactory.OpenSession())
           {
               // var m8 = session.CreateCriteria(typeof(Movies)).Add(Restrictions.Eq("Genre", "Guerre1234")).UniqueResult<Movies>();
               //var m8 = session.Get<Movies>(2);
               var m8 = session.CreateQuery("from Parent10 p where p.id1 =: id1 and p.id2 =: id2")
                       .SetString("id1", "1")
                       .SetString("id2", "2")
                       .SetCacheable(true)
                       .SetCacheRegion("Region1")
                       .Future<Parent10>()
                       //.Enumerable<Parent10>()
                       .First<Parent10>();
              // Console.WriteLine("Id > " + m8.id1 + "Genre > " + m8.id2 + " Price >  " + m8.ParentName);

               //Console.ReadLine();
              // m8.Price = 2; session.Flush();
              // session.Close();
               Console.WriteLine("End Session 1");
           }
           using (var session = sessionFactory.OpenSession())
           {
               //var m8 = session.CreateCriteria(typeof(Movies)).Add(Restrictions.Eq("Genre", "Guerre1234")).UniqueResult<Movies>();
               var m8 = session.CreateQuery("from Parent10 p where p.id1 =: id1 and p.id2 =: id2")
                       .SetString("id1", "1")
                       .SetString("id2", "2")
                       .SetCacheable(true)
                       .SetCacheRegion("Region1")
                       .Future<Parent10>()
                       //.Enumerable<Parent10>()
                       .First<Parent10>();
             //  Console.WriteLine("Id > " + m8.id1 + "Genre > " + m8.id2 + " Price >  " + m8.ParentName);
               var m9 = session.CreateQuery("from Parent10 p where p.id1 =: id1 and p.id2 =: id2")
                      .SetString("id1", "1")
                      .SetString("id2", "3")
                      .SetCacheable(true)
                      .SetCacheRegion("Region1")
                      .Future<Parent10>()
                   //.Enumerable<Parent10>()
                      .First<Parent10>();
               Console.Read();
               var m10 = session.CreateQuery("from Parent10 p where p.id1 =: id1 and p.id2 =: id2")
                      .SetString("id1", "1")
                      .SetString("id2", "2")
                      .SetCacheable(true)
                      .SetCacheRegion("Region1")
                      .Future<Parent10>()
                   //.Enumerable<Parent10>()
                      .First<Parent10>();
              // Console.ReadLine();
               //session.Close();
               Console.WriteLine("End Session 2");
           }

Wednesday, 14 November 2012

Define a column as guid as type

A quick tips to define a column as a guid

create table DevenvaGuidTips (
guid uniqueidentifier PRIMARY KEY DEFAULT NEWSEQUENTIALID() ROWGUIDCOL
,.....



MSDN :
Unlike columns defined with the IDENTITY property, the Database Engine does not automatically generate values for a column of type uniqueidentifier. To insert a globally unique value, create a DEFAULT definition on the column that uses the NEWID or NEWSEQUENTIALID function to generate a globally unique value