Parallelismo nelle applicazioni ASP.NET

by Marco 6. marzo 2010 13.33

A tutti coloro che sviluppano applicazioni ASP.NET o librerie che possono essere usate in applicazioni di questo tipo, consiglio la lettura di un post molto interessante scritto dal team delle TPL:

http://blogs.msdn.com/pfxteam/archive/2010/02/08/9960003.aspx

il succo del discorso è il fatto che frameworks come asp.net sono già “paralleli” e “scalabili” by-design e che l’introduzione di ulteriore parallelismo potrebbe portare ad un degrado delle performance. Questa affermazione nasce dal fatto che solitamente un’applicazione web è tanto più “perfomante” tante più richieste al secondo riesce a soddisfare. Il runtime di asp.net cerca di sfruttare al massimo le risorse che ha disposizione, come ad esempio utilizzare tutti i core dei nostri server. Chiaramente introdurre ulteriore parallelismo in un ambiente che fa già uso di tutte le risorse di “calcolo” possibili non fa altro che aggiungere latenza agli altri utilizzatori di tale risorse, nel caso di asp.net significa che il runtime dovrà “condividere” i core con altre attività che richiedono la loro parte di potenza di calcolo. Tutto questo significa che il parallelismo non è sempre positivo, ma va usato con “attenzione”, a seconda dell’ambiente in cui si sta operando. Nel caso di ASP.NET l’introduzione di codice parallelo/asincrono ha senso se l’attività che stiamo facendo comprende attività di I/O, in questo modo liberiamo risorse(il thread che ha effettuato la richiesta di I/O; tanto la testina dei dischi o il web service che abbiamo chiamato possono lavorare senza che li dobbiamo per forza aspettare, questo diminuisce il numero di thread richiesti e abbassa il context switch)che possono essere utilizzate per fare altro(soddisfare nuove richieste). Nel caso in cui l’introduzione del parallelismo sia semplicemente dovuta a bisogni computazionali, le performance per una applicazione web ad alto carico(tante richieste al secondo) potrebbero peggiorare vistosamente, dato che i worker thread che si occupano di soddisfare le richieste devono anche essere impiegati per la computazione parallela(questo sottrare risorse per le richieste in ingresso). In questi casi potrebbe risultare più perfomante delegare a qualche altra risorsa come a un server di calcolo dedicato il compito di rendere il calcolo più performante(pagando il prezzo della chiamata out-of-proccess, chiaramente dobbiamo misurare e capire se ne vale la pena). La problematica non resta isolata allo sviluppo di applicazioni web, ma pensiamo allo sviluppo di una libreria che fa uso calcolo parallelo che viene poi utilizzata dalle nostre applicazioni web, il problema si ripresenta. Sarebbe utile avere la possibilità di specificare prima dell’utilizzo della libreria il “grado di parallelismo” richiesto.

Vi lascio alla lettura del post che riporta un bel diagramma di flusso che tutti dovremmo consultare prima di agire!

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

.Net | Concurrent Programming | Multithreading | Parallel Programming

“Disk Partition Alignment Best Practices for SQL Server 2008”

by Marco 24. febbraio 2010 17.17

Quando si parla di ottimizzazioni delle performance di SQL Server spesso si tende a focalizzarsi solo sulla “query” o sul “disegno del database” in questione. Un’altro aspetto di non poca importanza per le performance è il “dove” i nostri file di dati/log risiedono.

Se volete capire meglio come l’allineamento delle partizioni può darvi anche oltre il 30% in più di performance(“…Disk latency is a fundamental measure of disk performance…”) vi consiglio di leggere questo interessante “paper” sulle “best practices” da utilizzare prima di cominciare l’installazione del nostro amato DBMS.

http://msdn.microsoft.com/en-us/library/dd758814.aspx

buona lettura…

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

SQL Server

Grazie e buona fortuna Luca…

by Marco 22. febbraio 2010 19.58

Ho appena appreso(con un pò di dispiacere)dal suo blog che Luca Bolognese lascia Microsoft per una nuova esperienza. Per chi non sapesse chi è diciamo che è stata una delle menti che negli ultimi 10 anni ha contribuito a dare la “forma” al framework che oggi tutti conosciamo e amiamo; come lui stesso dichiara ha fatto parte del gruppo di lavoro ObjectSpaces indroducendo idee che oggi troviamo in LINQ e nell’Entity Framework, nonchè lavorato alla nascita/crescita di linguaggi come C#,VB e F# o concetti come i generics.

Chi volesse continuare a seguirlo può sottoscriversi al suo nuovo blog:

http://lucabolognese.wordpress.com/

Mi dispiace un pò che forse non lo vedremo più su un palco a raccontare con semplicità, simpatia ed estrema chiarezza cose non banali(anche grazie al suo divertente accento poco americano e molto italiano ;-P ).

Lo seguo praticamente da quando ho cominciato a fare questo mestiere, non posso che ringraziarlo e fargli un in bocca al lupo per il futuro…è anche per persone come lui che dovremmo essere orgogliosi di essere Italiani.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Reactive Extensions e IObservable/IObserver

by Marco 12. febbraio 2010 16.34

Fino ad oggi siamo stati abituati a far interagire le nostre applicazioni con l’ambiente in cui queste vivono in maniera “interattiva”, nel senso che è il nostro programma che “interroga” lo stato dell’ambiente e agisce di conseguenza. Per fare un esempio pensiamo all’interfaccia IEnumerable, essa ci restituisce un IEnumerator che ci permette attraverso la chiamata al metodo MoveNext() di ottenere un elemento(nella proprietà Current); in tal senso siamo “interattivi” ovvero siamo noi che chiediamo il prossimo elemento all’enumeratore. Un’altro modo di approcciare è quello di essere “reattivi” ovvero metterci nelle mani dell’ “ambiente”(l’ambiente nel nostro caso potrebbe essere rappresentato da una semplice classe) e lasciare a lui il compito di “attivarci”. Questo modo di lavorare può così essere definito “basato su eventi” e “asincrono”(by design, è l’ambiente che ci attiva e non sappiamo quando). Dalla versione 4.0 del .NET Framework abbiamo a disposizione 2 nuove interfaccie nate proprio allo scopo di permetterci di creare ambienti che siano “reattivi”(per versioni più vecchie di framework le possiamo scaricare insieme all Rx Framework di cui parliamo tra un pò). Le interfaccie in questione sono System.IObservable<> e System.IObserver<>. Vediamole in dettaglio:

public interface IObservable<out T>
{
      IDisposable Subscribe(IObserver<T> observer);
}

public interface IObserver<in T>
{
      void OnCompleted();
      void OnError(Exception error);
      void OnNext(T value);
}

Se le guardiamo con attenzione ci accorgiamo subito che queste due interfacce sono matematicamente il duale di IEnumerable/IEnumerator e ci permettono di avere un funzionamento di tipo “push” invece che il classico “pull” dell’IEnumerable/IEnumerator. Quando dico duale intendo il fatto che:

- per quanto riguarda IObservable/IEnumerable al posto del metodo GetEnumerator() che ritorna IEnumerable abbiamo il metodo Subscrible che accetta un parametro di tipo IObserver

- per quanto riguarda IObserver/IEnumerator non abbiamo più il metodo MoveNext() che ci permette di spostarci sul “prossimo” elemento(che verrà messo in Current), ma abbiamo il metodo OnNext(void) che ci “passa”(quando l’”ambiente” vuole) l’elemento corrente

-nell' IEnumerator il metodo MoveNext() comunica con un booleano se ci sono ancora elementi invece nel caso dell’IObserver abbiamo il metodo  void OnCompleted()

-nel caso di eccezioni nell’ IEnumerator queste vengono sollevate alla chiamata del MoveNext() mentre nell IObserver abbiamo un metodo OnError che ci fornisce il dettaglio dell’errore

Detto questo; i campi di applicazione di questa metodologia basata su eventi asincroni sono innumerevoli e vanno dalla scrittura di “reazioni”(per rendere l’idea) ad eventi di una applicazione WPF, all’utilizzo nel mondo “asicrono” per natura del web e in qualsiasi parte del nostro codice dove non siamo noi che “possiamo” decidere quando “andare avanti”, ma dove è l’ “ambiente” che ce lo comunica.

Parallelamente a questo in casa Microsoft è nato un progetto dai DevLabs chiamato “Reactive Extensions for .NET (Rx)”, con lo scopo di creare degli extension method che permettano(come per IEnumerable) di effettuare delle LINQ query su oggetti di tipo IObservable come possono ad esempio diventare normali eventi .NET o librerie che utilizzano il pattern APM(Asynchronous Programming Design Patterns), ma non solo. In questa libreria abbiamo molti extension method che ci permettono di effettuare “composizioni” anche molto complesse di oggetti IObservable senza doverci preoccupare di problematiche come sincronizzazione, multithreading, coordinamento tra i vari “input streams”(alla fine se devo unire tra loro più IObservable in qualche modo devo sincronizzare i vari OnNext()).

Un’ esempio dell’applicazione di questo pattern potrebbe essere lo sviluppo di una classe che permetta di mettersi in ascolto di messaggi che arrivano in modo “asincrono” da un WebService WCF con un contratto di CallBack, ad esempio con il seguente contratto:

namespace WCFService
{   
    [ServiceContract(CallbackContract=typeof(IEvent))]
    public interface IEventService
    {
        [OperationContract]
        void Subscribe();
        [OperationContract]
        void Unsubscribe();
    }

    [ServiceContract]
    public interface IEvent
    {
        [OperationContract]
        void EventFired(XElement data);
    }
}

Subscribe/Unsubscribe servono per abbonare/disabbonare il client e il contratto di callback ha come argomento un XElement di questa forma:

<Order id="10" customerId="1" xmlns="urn:GestioneOrdini" />

l’xml porta un’ipotetico OrderId e CustomerId.
La natura “event based” del funzionamento del servizio si presta bene a costrure un oggetto di tipo IObservable che permetta lato client di mettersi in ascolto per determinati tipi di ordine, magari solo quelli fatti da un determinato customer(esempio customerId == 1). Lato client il codice “standard” WCF per poter gestire le callback è la costruzione di un oggetto che implementa l’interfaccia di callback  per passarne poi un’instanza in fase di creazione al proxy che effettua le chiamate, nel nostro caso:

class CallbackClass : WCFClientProxy.IEventServiceCallback
{
          public delegate void ServiceFire(object sender, ServiceEvent data);
          public event ServiceFire EventFireEvent;
          public void EventFired(XElement data)
          {
              if (this.EventFireEvent != null)
                  this.EventFireEvent(this, new ServiceEvent { Data = data });
          }
}

nella mia implementazione ho deciso di far sollevare un’evento al momento dell’arrivo di un messaggio dal servizio, l’evento in questione ha un EventArgs del tipo:

public class ServiceEvent : EventArgs
{
    public XElement Data { get; set; }
}

la proprietà “Data” porta chiaramente il payload Xml ricevuto. Grazie all Rx framework e alle nostre 2 nuove interfaccie possiamo permettere a chi utilizza il servizio di scrivere un codice del tipo:

class Program
{
       static void Main(string[] args)
       {
           WCFServiceListener listener = new WCFServiceListener();

          var xs = from ev in listener
                        where ((int)ev.EventArgs.Data.Attribute("customerId")) == 1
                        select ev;

           IDisposable subscription = 
                    xs.Subscribe(e => Console.WriteLine(e.EventArgs.Data));                         

           Console.ReadKey();

           subscription.Dispose();

           Console.ReadKey();
       }
}

WCFServiceListener è una classe che implementa IObservable<T> che al suo interno racchiude la logica di Subscribe/Unsubscribe; la parte più interessante è l’implementazione del metodo Subscribe dell’interfaccia:

public IDisposable Subscribe(IObserver<IEvent<ServiceEvent>> observer)
      {
          if (TraceDispose._subscriblerCount == 0)
                  _proxy.Subscribe();
          return
             new TraceDispose(Observable.FromEvent<ServiceEvent>(
                        _callBackClass,
                        "EventFireEvent")
                      .Subscribe(observer)
, _proxy);
      }

attraverso un metodo dell’ Rx framework(metodo statico FromEvent della classe Observable) creo un IObservable a partire da un’evento(nel nostro caso EventFireEvent della classe CallbackClass) e da un’instanza dell’oggetto(_callBackClass passata al proxy in fase di creazione) che può sollevare un evento con quel nome. La classe TraceDispose serve solo per la MIA implementazione interna a tenere il conto di quanti si sono “abbonati” al servizio per chiamare il metodo _proxy.Unsubscribe() in caso TraceDispose._subscriblerCount sia uguale a 0.

Tornando al codice del nostro main possiamo vedere come diventa estremamente chiaro e facile capire cosa stiamo facendo:

1)creo il mio IObservable

WCFServiceListener listener = new WCFServiceListener();

2)attraverso l’extension method “Where” dell’Rx filtro i messaggi che arrivano ricevendo solo quelli in cui il customerId è 1.

var xs = from ev in listener
                        where ((int)ev.EventArgs.Data.Attribute("customerId")) == 1
                        select ev; 

3) 
       IDisposable subscription = 
                    xs.Subscribe(e => Console.WriteLine(e.EventArgs.Data));                         

a questo punto mi “abbono” all’IObservable(questa versione di Subscribe fa parte sempre dell’ Rx framework, lo possiamo notare in quanto la firma dell’interfaccia non porta un metodo che accetta delle lambda, è l’overload che crea per noi un IObserver che in caso di chiamata OnNex() chiama il nostro delegate) e passo come delegate in caso di OnNext(quando arriva il messaggio dal server) la stampa in console del messaggio Xml.

Da questo punto in poi la mia applicazione è in ascolto in modo asincrono del servizio e appena arrivano gli ordini lo vediamo stampato in console, ad esempio:

Observable

possiamo notare il fatto che customrId è sempre 1 grazie alla nostra query LINQ sull’IObservable. Per disabbonarsi dobbiamo semplicemente chiamare Dispose sull’oggetto che ci viene ritornato in fase di Subscribe(Subscribe ritorna un oggetto IDisposable come da interfaccia) :

subscription.Dispose();

Naturale vero?A me piace un sacco, finalmente una sintassi “intuitiva” per tutte quelle applicazioni che “reagiscono” all’ambiente, supportato da un sacco di possibilità di “composition”(Rx framework ed extension method vari) e senza dover gestire problematiche come concorrenza e sincronizzazione.

Se volete approfondire questa tecnologia vi consiglio di farvi un giro sul portale ufficiale

Reactive Extensions for .NET (Rx)

Rx è utilizzabile con il .NET Framework 3.5 SP1,.NET Framework 4.0 e Silverlight 3

Se volete scaricare la demo del post

attenzione la demo non deve essere usata in linea…non è stata testata e potrebbe presentare problemi di sincronizzazione e di gestione delle eccezioni…ah serve VS2010(Beta2)

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

.Net | Concurrent Programming | Multithreading

Dynamic Language Runtime .NET 4.0(Beta 2)

by Marco 20. gennaio 2010 14.13

Nel framework 4.0 è stato aggiunto un insieme di classi che ci permettono di rendere il nostro codice e il .NET framework in generale “dinamico”. Cosa intendo per “dinamico”? Prendiamo ad esempio un semplice frammento di codice C#:


MyClass c = new MyClass();
c.Foo();

dal momento che questo codice compila possiamo affermare con sicurezza che la classe MyClass ha un metodo Foo() che viene invocato sull’istanza c. Questa assunzione la fa anche il compilatore che verifica a compile-time che quello che il nostro amato e “statico” C# esprime sia corretto. Quando dico statico intendo il fatto che se utilizziamo un linguaggio “statico”(come C# e VB) dobbiamo specificare il tipo dell’oggetto(MyClass) a design-time, ovvero indico con precisione al compilatore quale sarà il codice del metodo Foo() che dovrà essere eseguito a runtime. Nel nostro esempio dovrò eseguire il metodo Foo() definito nella classe MyClass sull’istanza riferita da c.

Il sistema dei tipi del .NET Framework è fatto da tipi “statici” nel senso che noi dichiariamo al momento della scrittura del codice il “tipo” che vogliamo utilizzare e il compilatore al momento della compilazione controlla che quello che abbiamo scritto sia “staticamente” corretto(che il tipo esista e abbia i vari membri che vogliamo utilizzare).

Con .NET 4.0 possiamo rendere il semplice frammento di codice dinamico, esempio(C#):


dynamic c = MyClass();
c.Foo();

specificando la keyword dynamic indichiamo al complilatore che il riferimento c punta ad un oggetto “dinamico” nel senso che al momento della compilazione non viene controllato se Foo() esiste, ma a “runtime” l’infrastruttura DLR(Dynamic Language Runtime) cerca il membro Foo() e lo esegue, sollevando un’eccezione se il membro non viene trovato. Questo significa che quando dichiariamo un tipo dynamic il compilatore attraverso il nuovo insieme di classi(System.Dynamic namespace) crea i “metadati” che serviranno a runtime per “risolvere” i membri. Diciamo che è come avere tutti membri di una classe virtuali, ma la risoluzione viene fatta a runtime da una “logica” custom(questa è una mia libera interpretazione).

Chiaramente possiamo noi stessi creare dei tipi dinamici, ereditando da una classe System.Dynamic.DynamicObject e facendo l’override di alcuni metodi.

Vediamo un esempio reale. Mi capita spesso di dover lavorare con file Xml attraverso la classe XElement. Dato il seguente file Xml:

<?xml version="1.0" encoding="utf-8" ?>
<Anagrafiche>
  <Anagrafica id="1">
    <Nome>Marco</Nome>
    <Cognome>Rossignoli</Cognome>     
    <Contatti>
      <Cells>
        <Cell tipo="vodafone">+1234567890</Cell>
        <Cell tipo="wind">+0987654321</Cell>       
      </Cells>
      <Emails>
        <Email>nospam@nospam.no</Email>
        <Email>nospam2@nospam.no</Email>
        <Email>nospam3@nospam.no</Email>
      </Emails>
    </Contatti>
  </Anagrafica>
  <Anagrafica id="2">
    <Nome>Mario</Nome>
    <Cognome>Rossi</Cognome>
    <Contatti>
      <Cells>
        <Cell tipo="vodafone">+6789012345</Cell>
        <Cell tipo="3">+6543217890</Cell>
      </Cells>
      <Emails>
        <Email>nospam4@nospam.no</Email>
        <Email>nospam5@nospam.no</Email>
        <Email>nospam6@nospam.no</Email>
      </Emails>
    </Contatti>
  </Anagrafica>
</Anagrafiche>

devo leggere i vari elementi e attributi e stamparli in console. Posso utilizzare le classiche API della classe XElement in questo modo:

XElement el = XElement.Parse(File.ReadAllText("Anagrafica.xml"));

foreach (var anagraficaElement in el.Descendants("Anagrafica"))
{
    Console.WriteLine("id:{0}", anagraficaElement.Attribute("id").Value);
    Console.WriteLine("Nome:{0}", anagraficaElement.Element("Nome").Value);
    Console.WriteLine("Cognome:{0}", anagraficaElement.Element("Cognome").Value);
    Console.WriteLine("Contatti");

    foreach (var cell in anagraficaElement.Element("Contatti").Descendants("Cell"))
    {
        Console.WriteLine("Cellulare:{0} tipo:{1}", cell.Value, cell.Attribute("tipo").Value);
    }

   foreach (var email in anagraficaElement.Element("Contatti").Descendants("Email"))
   {
         Console.WriteLine("Email:{0}", email.Value);
   }

     Console.WriteLine("-----");
}

come possiamo vedere dal codice, per poter leggere gli attributi e gli elementi devo conoscere il funzionamento dell’Xml e delle API di XElement. Non sarebbe più comodo se potessi scrivere lo stesso codice in questo modo?

foreach (var anagrafica in el.Anagrafiche)
{
     Console.WriteLine("id:{0}", anagrafica.id);
     Console.WriteLine("Nome:{0}", anagrafica.Nome);
     Console.WriteLine("Cognome:{0}", anagrafica.Cognome);
     Console.WriteLine("Contatti");

     foreach (var contatti in anagrafica.Contatti)
     {
          foreach (var cellulari in contatti.Cells)
          {
              Console.WriteLine("Cellulare:{0} tipo:{1}", cellulari.Cell, cellulari.tipo);
          }

          foreach (var email in contatti.Emails)
          {
              Console.WriteLine("Email:{0}", email.Email);
          }
      }

      Console.WriteLine("-----");

}

La “nuova” sintassi è chiaramente più chiara e molto più agnostica ai vari concetti dell’xml(elementi, attributi etc…) e di XElement, l’unica cosa che dobbiamo fare è “leggere” l’xml e richiedere l’elemento/attributo che ci interessa, qualcuno a runtime saprà come farlo.

Il DLR ci permette di realizzare questa “magia”, ovvero tutto quello che dobbiamo fare è rendere “dinamici” gli oggetti che devono “risolvere a runtime” i vari membri. Nel nostro esempio sono i riferimenti in grassetto. Cerco di spiegarmi meglio, l’idea è demandare ad un nostro pezzo di codice l’effettiva risoluzione delle varie proprietà richieste, come ad esempio l’id di anagrafica, il nome di anagrafica, il Cell di cellulari etc…il codice completo risulterà così:

XElement doc = XElement.Parse(File.ReadAllText("Anagrafica.xml"));

dynamic el = doc.AsDynamic();

foreach (var anagrafica in el.Anagrafiche)
{
    Console.WriteLine("id:{0}", anagrafica.id);
    Console.WriteLine("Nome:{0}", anagrafica.Nome);
    Console.WriteLine("Cognome:{0}", anagrafica.Cognome);
    Console.WriteLine("Contatti");

    foreach (var contatti in anagrafica.Contatti)
    {
        foreach (var cellulari in contatti.Cells)
        {
             Console.WriteLine("Cellulare:{0} tipo:{1}", cellulari.Cell, cellulari.tipo);
        }

        foreach (var email in contatti.Emails)
        {
              Console.WriteLine("Email:{0}", email.Email);
        }
    }

    Console.WriteLine("-----");

  }

semplicemente ci serve un modo per avere un “wrapper” dynamic sul nostro XElement, sarà la logica che mettiamo nel nostro DynamicObject a cercare attraverso le varie API XElement l’elemento/attributo richiesto. Nella MIA implementazione ho usato un’extension method su XElement per eleganza, ma non è obbligatorio in quanto come vedremo tra un secondo la definizione del nostro dynamic object è una normale classe che eredita da System.Dynamic.DynamicObject e ha un costruttore al quale possiamo passare l’istanza di XElement.

E ora vediamo la definizione della classe “magica”:

  public static class DynamicXmlExtension
  {
      public static dynamic AsDynamic(this XElement xml)
      {
          return new DynamicXml(xml);
      }

       public class DynamicXml : DynamicObject
      {
          public DynamicXml(XElement element)
          {
              _element = element;
          }

          private bool TryGetMemberLogic(GetMemberBinder binder, out object result)
          {
               ….logica interna di ricerca degli elementi/attributi che nascondo volontariamente
               in quanto incompleta, non testata e a scopo dimostrativo…alla fine non fa 
               altro che utilizzare binder.Name con le API XElement             
          }

          public override bool TryGetMember(GetMemberBinder binder, out object result)
          {
                return TryGetMemberLogic(binder, out result);
          }

          public override string ToString()
          {
              return _element.ToString();
          }

        }

  }


la classe contiene 2 cose fondamentali: la prima è l’extension method che ritorna l’oggetto di tipo dynamic e la seconda è l’implementazione del nostro tipo DynamicXml che eredita da System.Dinamic.DynamicObject. Il segreto per realizzare la “magia” sta nel ridefinire dei metodi della classe base DynamicObject. Abbiamo un bel pò di metodi che ci permettono di gestire la risoluzione di praticamente qualsiasi membo di una classe(ma non solo). Nel nostro esempio quello che ho dovuto ridefinire è il Get di un membro(ricodate anagrafica.Nome), quindi ho fatto l’override di TryGetMember(come possiamo notare tutti i metodi cominciano con TryXXX). TryGetMember mi fornisce 2 parametri, il primo GetMemberBinder attraverso la proprietà Name mi comunica il nome del membro richiesto(ad esempio in caso di anagrafica.Nome binder.Name sarà Nome, GetMemeberBinder contiene altre interessanti proprietà che non tratterò per semplicità) il secondo è una variabile di out che la mia logica di ricerca deve assegnare. Insomma in soldoni cerco il binder.Name nel mio xml attraverso le API XElement e quando trovo l’elemento lo assegno a result. I parametri forniti da questi metodi variano a seconda della caratteristica che stiamo cercando di risolvere in modo “dinamico” a runtime(ogni TryXXX ha i suoi parametri tipizzati).

Carino o no?

Il DLR è un framework molto potente ed interessante, oltre a fare queste “magie” viene impiegato per risolvere tanti altri problemi, per una trattazione approfondita potete partire da qua Dynamic Language Runtime Overview.

Per scaricare una demo funzionante clicca qua

Attenzione non utilizzate il codice in produzione, non è completo non è testato ed è a scopo dimostrativo; inoltre mi sono inventato una mia logica di ricerca che può non piacere o risultare scomoda…ereditate e implementate la vostra ;-)

Correntemente valutato 5.0 da 2 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net

System.Threading.Tasks.Task implementa IAsyncResult(.NET 4.0 Beta 2)

by Marco 13. gennaio 2010 14.18

L’ IAsyncResult design pattern è un pattern per l’esecuzione asincrona di operazioni che viene largamente usato all’interno del framework in ogni sua parte; consiste nella scrittura di due metodi che permettono di iniziare un’operazione in modo asincrono e di un metodo che la completa, un esempio di una classe che implementa questo pattern potrebbe essere:

    public class AsyncLib
   {
       public int Foo(int parameter)
       {
           ...operazione
       }

       public IAsyncResult BeginFoo(int parameter, AsyncCallback callback, object state)
       {
          ...chiamata a Foo(int parameter) in thread separato e ritorno di un oggeto
          che implementa IAsyncResult
       }

       public int EndFoo(IAsyncResult asyncResult)
       {
           …se l’operazione è finita torno il risultato altrimenti blocco il thread che ha chiamato
       }
   }

il funzionamento è abbastanza semplice: chiamo BeginOperazione che ritorna immediatamente un’istanza di una classe che implementa l’interfaccia IAsyncResult che possiamo interrogare per sapere a che punto è la nostra operazione, o possiamo passare un delegate di tipo AsyncCallBack al metodo stesso per farci chiamare una volta che l’operazione è finita. Quando l’operazione asincrona è terminata(lo sappiamo grazie all’oggetto IAsyncResult o perchè ci viene chiamata la callBack) dobbiamo chiamare il metodo EndOperazione e passare l’istanza ritornata dal metodo BeginOperazione, a quel punto abbiamo in mano il risultato e possiamo farci quello che vogliamo. Questa spiegazione non è completa, ma non è lo scopo del post vi lascio il link alla documentazione ufficiale Asynchronous Programming Design Patterns. Lo stesso pattern viene implementato automaticamente se utilizziamo un delegate, ovvero viene compilata per noi una classe con i metodi Begin/End.

Se dobbiamo far implementare questo pattern alle nostre librerie la cosa più complessa da fare è quella di creare una classe che implementi IAsyncResult nel modo corretto e sincronizzare il tutto con il lavoro asincrono. Le cose da prendere in esame non sono poi così banali, dobbiamo accodare il lavoro da “qualche parte”(dipende da quale tipo di thread vogliamo utilizzare, thread pool, un nostro thread etc…),implementare ciò che l’interfaccia ci richiede(le cui cose più complesse sono come gestire l’oggetto di sincronizzazione e alcuni stati richiesti dall’oggetto in modo perfomante e corretto) e chiamare la callback in caso venga fornita alla fine dell’operazione asincrona. Problema ancora più subdolo è il fatto che la nostra libreria potrebbe essere chiamata in contesti di threading diversi, quindi in caso di callback dobbiamo assicurarci che tutto rispetti le regole di questo contesto. L’implementazione costa un pò di righe di codice che non sono così banali a chiunque.

Il team delle Task Parallel Library ha fortunatamente pensato anche a questo e ha gentilmente fatto implementare alla classe Task l’interfaccia IAsyncResult. Questo fa si che scrivere con .NET 4.0 un custom IAsyncResult diventi un gioco da ragazzi, di seguito un esempio:

  public class AsyncLib
   {
       public int Foo(int millisecond)
       {
           //simulo un carico di lavoro
           Thread.Sleep(millisecond);
           //simulo un risultato
           return new Random().Next(int.MaxValue);
       }

       public IAsyncResult BeginFoo(int i, AsyncCallback callback,
           object state)
       {
          

          Task<int> task = new Task<int>(o => Foo(i), state);

           task.ContinueWith(t =>
           {
               if (callback != null)
                   callback(t);
           },
           SynchronizationContext.Current == null ?
           TaskScheduler.Default :
           TaskScheduler.FromCurrentSynchronizationContext()
);

           task.Start();

           return task;

         }

       public int EndFoo(IAsyncResult asyncResult)
       {
           Task<int> result = asyncResult as Task<int>;

           if (result == null)
               throw new ArgumentException("Bad async result.");

           return result.Result;
       }
   }

cosa ne dite?Semplicemente la nostra Begin ritorna un task che esegue prima la chiamata a Foo in modo asincrono e poi attraverso ContinueWith esegue la callback(in caso venga passata) nel constesto di threading adeguato
(TaskScheduler.FromCurrentSynchronizationContext() o TaskScheduler.Default). Se contiamo le righe di codice sono 4 per la Begin(sono dovuto andare a capo per farci stare tutto)e 3/4 per la End. Con così poco semplice codice utilizzare questo pattern sarà alla portata di tutti, in quanto l’unica cosa non chiarissima è forse il check del contesto per scegliere il TaskScheduler adeguato, ma siamo in Beta 2 magari qualcosa di meglio lo pensano, per il resto non si vede l’ombra di XXXResetEvent, lock, volatile, ThreadPool, Thread,WaitXXX etc….sono solo 2 Task uno “attaccato” alla fine dell’altro…semplice no?

…ah dimenticavo, chiaramente funziona ovunque, Console app, Windows Form app, WPF app etc…

Se volete una demo contattatemi

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

.Net | Concurrent Programming | Multithreading

TaskScheduler.FromCurrentSynchronizationContext() (.NET 4.0 Beta 2)

by Marco 7. gennaio 2010 20.39

Tutti coloro che hanno sviluppato interfaccie che gestiscono una grande quantità di dati o che eseguono lunghe operazioni, si sono dovuti scontrare prima o poi con il problema del “blocco” dell’interfaccia dovuto al fatto che la “pesantezza” dell’operazione veniva eseguita nel famoso “thread di UI” cioè quel thread che ha il compito di gestire la coda dei messaggi associata ai controlli che lui stesso ha creato. L’indisponibilità di questo thread(speso a fare operazioni “lunghe”) porta l’interfaccia a bloccarsi in quanto i messaggi nella coda non vengono gestiti e quindi la nostra interfaccia non si può ridisegnare correttamente o reagire all’attività dei nostri utenti.

Per ovviare a questo problema l’unica soluzione è quella di effettuare l’operazione “lunga” in un thread separato, così da liberare il “thread di UI” che può senza problemi gestire la sua bella coda di messaggi. L’unico problema di questo approccio è il fatto che nel momento che dobbiamo riflettere il risultato dell’ operazione “lunga” sull’interfaccia non lo possiamo fare da un thread che non sia quello di UI. L’unico modo di risolvere questo problema è quello di fare il “marshal” sul “thread di UI” ovvero ci serve un meccanismo per passare i dati al thread di UI e far fare a lui la modifica dei nostri controlli. I 2 principali framework grafici che “soffrono” di questo problema sono chiaramente Windows Form e WPF. Su internet si trovano tonnellate di articoli che spiegano come fare il “marshal” nelle varie piattaforme, l’operazione è abbastanza semplice, l’unico difetto è che purtroppo le modalità sono differenti da un framework ad un’altro(esempio l’interfaccia ISyncronizeInvoke per Windows Form e la classe Dispatcher per WPF) e questo è un bel problema per chi deve ad esempio scrivere una libreria che deve essere asincrona e utilizzabile ALLO STESSO MODO su qualsiasi piattaforma grafica venga usata(diciamo che più che di piattaforma grafica possiamo parlare di contesto di esecuzione).

Una delle possibilità che abbiamo per generalizzare la possibilità di gestire il marshal è quella di utilizzare la classe SyncronizationContext che attraverso la proprietà statica Current ci mette a disposizione un paio di metodi(Post se vogliamo un’esecuzione asincrona o Send la vogliamo sincrona) per eseguire un delegate nel giusto Context(diciamo il thread di UI se stiamo usando WPF o WindowsForm, ma context è un concetto generico).

Ad esempio se vogliamo modificare il content di un bottone in WPF un’ipotetico handler dell’evento click potrebbe essere:

private void button1_Click(object sender, RoutedEventArgs e)
{          
  SynchronizationContext context = SynchronizationContext.Current;
   ThreadPool.QueueUserWorkItem(a =>
           {
              System.Threading.Thread.Sleep(5000);//Simulo il carico di lavoro
             context.Post(o=>this.button1.Content=o,"Nuova Content del bottone"); //modifico una proprietà di interfaccia
           });
  }

in questo esempio prima salvo il Current context attraverso la proprietà SyncronizationContext.Current e poi in un thread del thread pool di .NET(quindi non un thread di UI) faccio il “marshal” asincrono usando il metodo Post sul context salvato(il context nel thread di thread pool non è valido). Il fatto che sto utilizzando WPF significa che qualcuno(il runtime di WPF) ha “attaccato” come Current context una implementazione personalizzata(la classe è la DispatcherSynchronizationContext nel namespace System.Windows.Threading) della classe SynchronizationContext che al suo interno usa la classe Dispatcher per fare il marshal in modo corretto.

Questo significa che se devo eseguire operazioni asincrone, ma non voglio legarmi a nessuna piattaforma(non solo UI) applicativa utilizzando questa classe(sperando che qualcuno abbia correttamente implementato una versione della classe SyncronizationContext) e non voglio avere problemi nel momento in cui dovrò eseguire la “callback” di finalizzazione dell’operazione, utilizzare l’astrazione attraverso SyncronizationContext mi risolve il mio problema di “generalizzazione”.

Se volete scrivere ancora meno codice e restare ad un livello ancora più alto sotto il namespace System.ComponentModel troviamo la classe AsyncOperationManager che fa un pò di lavoro per noi(come ad esempio salvarsi il context o inizializzare un context di default se non è presente, come ad esempio in una console application, il default context utilizza il thread pool nel Send/Post)attraverso un metodo “factory” di operazioni asincrone, permettendoci di focalizzarci di più sul problema di “business” e meno su quello “tecnico”, il System.ComponentModel.BackgroundWorker si basa su questa classe.

Esempio:

private void button1_Click(object sender, RoutedEventArgs e)

//creo il wrapper per l’operazione asyncrona, controlla se il context esiste o ne
//imposta uno di default che usa il ThreadPool .NET
AsyncOperation operation = AsyncOperationManager.CreateOperation(null);                   

System.Threading.ThreadPool.QueueUserWorkItem(a =>
               {
                   System.Threading.Thread.Sleep(5000);//simulo il carico di lavoro
                  

                   //Faccio il post dell’operazione sul contesto giusto e notifico il
                   //context sottostante
                   operation.PostOperationCompleted(o =>
                   {
                       this.button1.Content = o;
                   }, "Nuova Content del bottone");                                      
               });
}

Il metodo PostOperationComplete notifica in modo automatico il Context sottostante che l’operazione è terminata, in caso il context in questione avesse bisogno di saperlo per motivi architetturali(altrimenti avremmo dovuto chiamare prima il metodo Post() e poi il metodo OperationCompleted()). L’esempio non è esaustivo, ma da l’idea del senso per cui è stato creato per approfondimenti cercate nella guida o sul web, lo scopo di questo blog non è l’AsyncOperationManager.

Fortunatamente anche con le Task Parallel Library abbiamo la possibilità di sfruttare questo meccanismo in modo veramente semplice…il codice è più chiaro della spiegazione:

private void button1_Click(object sender, RoutedEventArgs e)
       {
              Task.Factory.StartNew(() =>
               {
                   Thread.Sleep(5000);//Simulo il carico
                   return "Nuova Content del bottone";
               })
               .ContinueWith(taskPrecedente =>
                   {
                       this.button1.Content = taskPrecedente.Result;
                   }, TaskScheduler.FromCurrentSynchronizationContext()
                   );

       }

Il metodo ContinueWith accetta come parametro tra i suoi overload un’oggetto di tipo TaskScheduler il quale ha un metodo statico FromCurrentSynchronizationContext che si occupa di creare un TaskScheduler del giusto tipo per il contesto in cui siamo.
Questo significa che l’operazione pesante(StartNew()) viene fatta in un thread separato e l’assegnazione del risultato(ContinueWith()) al nostro controllo viene “postato” sul thread di UI, grazie al fatto che abbiamo indicato uno scheduler conscio del fatto che siamo in un contesto di funzionamento per quanto riguarda il threading “particolare”(sotto le coperte utilizza il SyncronizationContext).

Non so cosa ne pensate, ma la sintassi per scrivere codice asincrono lato client con le TPL(task parallel library) è un bel passo avanti e alla portata di tutti…buon divertimento.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Multithreading | .Net

Axum al PDC

by Marco 5. gennaio 2010 12.26

Ho già parlato in passato di questo “incubation project” e vi consiglio di guardare questa sessione di Niklas Gustafsson che illustra in modo molto chiaro il motivo per cui è necessario avere un linguaggio “ad hoc” per poter sviluppare in modo corretto/produttivo applicazioni parallele altamente scalabili sulle piattaforme multicore di oggi e domani.

Certamente non tutto il codice che scriviamo deve per forza essere parallelo, una GUI, una logica di business, il codice di accesso ai dati, non hanno sempre questi requisiti, ma vi sono alcune parti di un programma in cui questa possibilità può rendere l’applicazione molto più soddisfaciente.

Axum è un linguaggio che implementa il parallelismo attraverso il paradigma di comunicazione denominato “Message-Passing” dove l’idea principale è quella di avere degli agenti(concettualmente delle classi che fanno qualcosa) che operano su dei dati che definiscono il dominio(ad esempio le classi che contengono i dati su cui fare qualcosa). La chiave di tutto è il fatto che gli agenti possono scambiare tra loro dati solo attraverso messaggi che trasportano dati che possono essere usati in un dominio. Questa constraint da la possibilità di specificare che un agente ha la possibilità di modificare i dati di un dominio, operazione preclusa agli altri agenti che scambiano dati attraverso “copie” e non attraverso riferimenti ai dati stessi.

Gli elementi principali di Axum sono:

-Agenti: gli utilizzatori dei dati del dominio(possono stare in-process o out-of-process, permettendo così di avere un "distributed programming model").

-Dominio: i dati che vengono usati dagli agenti(in modo esclusivo ad esempio)

-Channel: l’interfaccia di comunicazione tra un agente e gli altri agenti

-Schema: definiscono le constraints sui channels e sui messaggi che vengono scambiati dagli agenti

Questo stile di programmazione permette di superare un bel po' di problemi a cui dobbiamo far fronte quando scriviamo un’applicazione che deve “andare in parallelo” ed essere diciamo “asincrona” e “scalabile”. I problemi fondamentali sono quelli dell’isolamento degli stati(evitare lo sharing di parti di memoria attraverso copie e non riferimenti diretti a questa), la sincronizzazione e locking(è un task complesso e pieno di insidie lasciamolo fare ad un runtime) , consumo di risorse(ogni thread in .NET consuma 1MB minimo), scalabilità(sfruttamento di multicore, minimizzare il context switch tra i thread etc…), ma ce ne sono anche altri meno macroscopici.

Il progetto è ancora nei Labs di Microsoft…speriamo non uccidano il bambino nella culla.

Buona visione http://microsoftpdc.com/Sessions/VTL02

P.S.: buon 2010 a tutti.

Correntemente valutato 5.0 da 1 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

.Net | Concurrent Programming | Parallel Programming

Windows HPC Server 2008 (High Performance Computing)

by Marco 2. dicembre 2009 19.17

Se avete “seriamente” bisogno di “performance” nelle vostre applicazioni vi consiglio di guardare questa sessione del pdc 2009 su Windows HPC Server 2008.

Praticamente questa estensione al sistema operativo Windows Server 2008(x64) permette di creare un cluster di server su cui distribuire calcoli. Nella sessione si vede come è possibile semplicemente aggiungendo qualche riga di codice .NET, permettere ad un servizio WCF(attraverso le HPC SOA Api) di essere utilizzato sfruttando il parallelismo del cluster, senza che il client debba sapere l’effettivo endpoint, ma usandone uno solo fornito dall’infrastruttura(il sistema prevede un broker che coordina le chiamate verso il cluster).

Come spiegato nel video questa tecnologia permette impostazioni e possibilità più “fini” confronto le classiche tecnologie di “load balancing” e il supporto a livello di Visual Studio e .NET framework rende il tutto molto appetibile e a basso impatto per uno sviluppatore “medio”.

E’ ancora in beta…ma non vedo l’ora di provarlo…buona visione.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Concurrent Programming | Parallel Programming

Ottimizzazioni del compilatore e multithreading: loop invariant

by Marco 18. novembre 2009 10.58

Codice(C#,VS2008,.NET 3.5):

public class LoopInvariant
   {
       int count = 0;
       public void Cicla()
       {
           while (this.count == 0) {}
       }
       public void Cambia()
       {
           this.count = 1;
       }
   }

fino a qua, nulla di particolare, questa classe non fa un bel niente, semplicemente abbiamo 2 metodi, un metodo Cicla() che esegue una while verificando che count sia uguale a 0, poi abbiamo Cambia() un metodo che cambia il contatore e lo porta a 1.

Ora usiamo questa classe(console application):

static void Main(string[] args)
       {
           LoopInvariant var = new LoopInvariant();
           ThreadPool.QueueUserWorkItem(o =>
           {
               System.Threading.Thread.Sleep(5000);
               ((LoopInvariant)o).Cambia();
               Console.WriteLine("Valore modificato");
           }, var);
           var.Cicla();
           Console.WriteLine("Fine test");
           Console.ReadKey();
       }

qua cosa succede; niente di particolare: istanzio la classe LoopInvariant, faccio partire in un thread separato(attraverso il threadpool di .NET) un pezzo di codice che si blocca per 5 secondi(Sleep(5000)) dopo di che chiama il metodo Cambia() sulla mia istanza e stampa che lo ha fatto.

Bene, compiliamo(in release). Lanciamo(CTRL+F5)…passano i 5 secondi…6…7….8….9….?!?!?!?!?

LoopInvariant

cavolo succede?perchè non stampa “Fine test”?ho cambiato il valore di count…dovrebbe stampare “Fine test” (visto che la condizione count == 0 è falsa) e fermarsi li ad aspettare la pressione di un tasto…

Il problema è che il Jit compiler analizzando il metodo Cicla() applica una ottimizzazione chiamata Loop-invariant code motion, ovvero dal fatto che la variabile count non viene “toccata” all’interno del corpo del while, il compilatore può concludere che count è “loop invariant” e così metterlo in una variabile temporanea prima di iniziare il loop(in un registro del processore magari, così evitiamo di dover risolvere l’indirizzo in ram della variabile ad ogni ciclo migliorando le prestazioni) , questo comporta che quanto l’altro thread chiama Cambia() sulla stessa istanza la modifica non viene “vista” dal nostro metodo Cicla() portanto ad un loop infinito. Cosa che genera ancora più confusione è che se facciamo il debug(F5) di questo codice tutto funziona correttamente in quanto le ottimizzazioni sono disabilitate in configurazione DEBUG.

Per disabilitare questa ottimizzazione occorre dichiarare la nostra variabile count come volatile, questo rende il nostro count esplicitamente non “loop invariant” , come Joe Duffy spiega nel suo libro:

“Load and stores of volatile variables can never be introduced or removed, both in .NET and VC++, because they are assumed to be constantly changing. As such, they aren’t eligible for being considered loop invariant and hoisted outside of loops…”

quindi basta cambiare il nostro codice in questo modo:

public class LoopInvariant
   {
       volatile int count = 0;
       public void Cicla()
       {
           while (this.count == 0) {}
       }
       public void Cambia()
       {
           this.count = 1;
       }
   }

a questo punto se compiliamo(sempre in release altrimenti le ottimizzazioni vengono soppresse per supporto al debug) e lanciamo(CTRL+F5)…1…2….3..4..5…e

LoopInvariant2

adesso il programma funziona come ci aspettavamo…

Attenzione questo non è il solo effetto della keyword volatile, ricordo che leggere da un campo volatile(o usare Thread.VolatileRead) equivale logicamente ad una acquire fence, mentre scrivere un campo volatile(o usare Thread.VolatileWrite) equivale logicamente ad una release fence.

La classe LoopInvariant chiaramente non serve ad un piffero ed è li solo per didattica, ma questo ci fa capire che la programmazione multithread “aggiunge” una dimensione che oggi non è gestita in modo automatico dai compilatori, nel caso della loop invariant fare quella ottimizzazione non cambiava la semantica del programma, ma il danno lo abbiamo visto tutti.

Occhio…

Fonti: Concurrent Programming on Windows

Correntemente valutato 5.0 da 1 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Concurrent Programming | Multithreading | Parallel Programming

Web Service?

by Marco 12. novembre 2009 19.26

“…deve usare il nostro web service che come da standard si autodocumenta attraverso il wsdl e le permette di interagire con i nostri sistemi…”

io penso…”…fico, sarà uno scherzo, grazie soap…”

download wsdl…..diamo un’occhiata…eeeeeeeeeee!?!??!!?!?

public string FintaOperazioneAltrimentiNonLavoroPiù(string auth,string parametriRicerca);

…e tonnellate di carta a spiegare come deve essere formattato l’xml dei parametri di ingresso e dei parametri di ritorno…allora ripenso ai capisaldi di SOAP…

Contracts should be designed to be as explicit as possible to minimize misinterpretation. Additionally, contracts should be designed to accommodate future versioning of the service via the extensibility of both the XML syntax and the SOAP processing model.

…cavolo almeno quell’auth…mettetelo in un custom soap header se non vi va bene niente di WS-Security…vabbè proviamo a chiamare e vediamo che succede…

eccezione dal servizio, cosa dice il soap fault?…Object not set to an instance….eeeeeeeee!?!?!?!?e ripenso ai capisaldi di SOAP

Internal (private) implementation details should not be leaked outside of a service boundary

…vabbè almeno usano .net…la classe XXX ha sollevato un'eccezione…spetta che mando la riga dell’errore allo sviluppatore, è nell’errore….

…ho capito l’errore…ho sbagliato il case di un elemento del parametro string da passare come xml…se fosse stato un contratto fatto con criterio questo errore me lo evitavo…

morale: sono stufo di “String XML HTTP POST Services”(POX services) spacciati per "Web Services SOA", per quello c'è REST ;-)

Correntemente valutato 5.0 da 1 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

Wcf

Non si finisce mai di imparare…

by Marco 13. ottobre 2009 18.40

Vi consiglio di dare una letta a questo postdel CRL Team dove vengono sfatati alcuni miti sul codice gestito e sul CLR.

Particolarmente interessanti trovo questi 2 punti:

-Generic co- and contra variance are new in .NET 4.0: la co e contro varianza è sempre stata supportata:

“…In IL, covariant type parameters are indicated by a ‘+’, and contravariant type parameters are indicated by a ‘-‘…”

semplicemente non è mai stata supportata dalla sintassi di C# e non ho mai visto quei simpatici simbolini durante il “disassembling”(fino all’IL di .NET 4.0) di codice gestito…credevo avessero aggiunto qualcosa all’IL nel 4.0…che ignorante :-)

-Everything is an object: questa la sapevo, ma diciamo che per chi insegna .NET è una bugia raccontata in buona fede…perdono. Inoltre trovo che molti testi “importanti” non dicano sempre la verità :-)

Molto interessante…buona lettura…e chiedo umilmente scusa per la bugia…

Correntemente valutato 5.0 da 1 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

.Net

Disk2vhd nuovo p2v da Sysinternals

by Marco 8. ottobre 2009 10.57

Segnalo un nuovo tool della suite “sysinternals tools” per creare dischi virtuali da una macchina fisica(physical to virtual):

Ecco il link del tool http://technet.microsoft.com/en-us/sysinternals/ee656415.aspx

La cosa più interessante oltre al fatto che ha un’interfaccia grafica molto semplice è il fatto che è possibile creare un disco virtuale mentre il sistema è on-line(senza dover fare boot o altro) in quanto sfrutta le features “Volume Snapshot” di Windows.

The difference between Disk2vhd and other physical-to-virtual tools is that you can run Disk2vhd on a system that’s online. Disk2vhd uses Windows’ Volume Snapshot capability, introduced in Windows XP, to create consistent point-in-time snapshots of the volumes you want to include in a conversion.”

Promette molto bene, stiamo a vedere.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Windows

Fences/Barriers in teoria…

by Marco 9. settembre 2009 18.34

Dopo aver letto questo mio precedente post , dovrebbe essere chiaro come sia possibile che stores/loads possano essere riordinati nel rispetto delle regole del memory model in cui il nostro codice gira.

Se ci pensiamo un attimo, la cosa non dovrebbe toccarci, nel senso che se il compilatore/processore aggiunge/toglie/sposta istruzioni per rendere tutto più performante a noi dovrebbe andare più che bene. Questo è effettivamente vero finchè non facciamo uso di tecniche di programmazione “lock free”, ovvero quando non viene fatto uso di primitive di sincronizzazione(lock(…),Monitor,Events,Mutex) per sincronizzare l’accesso a zone di memoria condivise da più thread. Questa tecnica, rende molto più scalabili e performanti le applicazioni multithread su più processori, in quanto il fatto di non mettere mai il thread in “wait” permette di avere un “throughput” maggiore a confronto di tecniche che utilizzano i lock(nessun thread “blocca” nessun altro thread, se non a basso livello, ma è trasparente a noi e viene fatto dal processore, niente context switch insomma). 

Perchè dovrebbero essere un problema quindi queste ottimizzazioni?
Perchè, mentre muovere istruzioni dal punto di vista di un solo thread quindi di un solo percorso di esecuzione non da nessuna inconsistenza, quando sono più di uno i thread che devono eseguire questo percorso in modo parallelo/contemporaneo il riordinamento di una store/load potrebbe inficiare il corretto funzionamento dell’algoritmo portando a inconsistenze e a difficili bugs da scovare/risolvere.

Per poter avere il controllo sul riordinamento(ottimizzazione) fatto da processore/compilatore, possiamo usare delle istruzioni cosiddette fences/barriers(recinto/barriera), attraverso le quali possiamo indicare al processore/compilatore quali tipi ottimizzazioni(spostamenti) sono possibili.

Ricordiamoci che le ottimizzazioni possono essere fatte a qualsiasi livello dello stack software, quindi sia a livello di compilazione che a livello di esecuzione(processore), mettere delle fence a livello di codice(compilatore) non significa metterle anche a livello di processore, tutto questo dipende dal runtime su cui state sviluppando, es:.NET, VC++, C etc..

Detto questo esistono vari tipi di fence(da ora in poi li chiamerò così e non barrier, ma sono la stessa cosa, dipende dal runtime/ambiente in cui state lavorando):

Full fence: nessuna stores o loads possono essere spostate al di là della fence, in tutte e due le direzioni(molte architetture mettono ad disposizione delle istruzioni come ad esempio MFENCE) quindi(pseudo codice):

load A
load B
store A

Fence

store B
store C
load C

le istruzioni stores/loads ABA e BCC non possono essere spostate al di là della fence in nessuna delle due direzioni, le istruzioni dopo la fence non possono muoversi prima, quelle prima non possono spostarsi dopo. Le full fence sono quelle più “rigide” e tutti gli altri tipi vengono usati per non sacrificare troppo le ottimizzazioni.

Store fence: simili alle full fence eccetto che si applicano solo alle istruzioni di stores e permettono lo spostamento delle loads. Quindi(pseudo codice):

load A
load B
store A

Store fence

store B
store C
load C

Le istruzioni loads A,B,C possono essere spostate prima/dopo della fence(questa fence è disponibile su x86 e x64 e viene generalmente esposta con l’istruzione SFENCE)

Load fence: sono il perfetto contrario delle store fence(e vengono comunemente espresse con l’istruzione LFENCE)

load A
load B
store A

Load fence

store B
store C
load C

Le istruzioni di stores A,B,C possono essere spostate prima/dopo della fence.

Come abbiamo detto prima le fence possono essere utilizzate a livello di processore(full fence, store fence, load fence), ma anche a livello di compilazione:

Acquire fence: assicurano che ne le stores ne le loads che ci sono dopo la fence possano essere spostate prima di questa. Le istruzioni che vengono prima possono essere spostate dopo.

load A
load B
store A

Acquire fence

store B
store C
load C

store B,c e load C non possono essere spostate prima della fence.

Release fence: assicurano che ne le stores ne le loads che ci sono prima della fence possano muoversi dopo della stessa. Le istruzioni dopo la fence possono essere spostate prima

load A
load B
store A

Release fence

store B
store C
load C

load A,B e store A non possono essere spostate dopo la fence.

Queste ultime due fence vengono usate dai complilatori e dall’architettura IA64, e hanno la peculiarità di essere applicate solo alla direzione e non al tipo di istruzione.

Dobbiamo assicurarci di applicare la fence sia a livello di compilatore che a livello di processore, in quanto sono 2 layer separati che possono in modo indipendente effettuare dei riordinamenti(in gergo si dice “move” o meglio “move after..” “move before..”).

Esistono vari modi di introdurre delle fence nel nostro codice e questo varia dalla piattaforma che stiamo usando(.NET,VC++, C), come ad esempio il marcare “volatile” una variabile con .NET o usare delle macro in VC++, ma ce ne sono altri e questo è argomento per un’altro post.

Per concludere è bene sottolineare che il riordinamento che viene effettuato a livello di compilatore/processore, rispetta sempre la “data dependence”(dipendenza dei dati) per non provocare errori logici durante le stores/loads(altro argomento un pò complesso che è bene trattare separatamente).

Fonti: Concurrent programming on Windows(Joe Duffy)

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

Concurrent Programming | Multithreading | Parallel Programming

Loads e Stores

by Marco 7. settembre 2009 12.12

Nel precedente post sui memory model ho parlato spesso di loads e stores.

Si ok, ma cosa vuol dire?

Allora quando parliamo di loads si intendono quelle istruzioni che spostano i dati da una locazione di memoria in un registro del processore, mentre le stores sono quelle istruzioni che spostano i dati da un registro del processore ad una locazione di memoria.

In una architettura load/store, le istruzioni di load e store solo le uniche istruzioni che accedono ai dati in memoria.

Esempio ad alto livello:

x = 1  Store, il valore 1 verrà spostato da un registro del processore all’indirizzo in memoria x
y = x Load, il valore in memoria x verrà spostato in un registro  del processore per essere utilizzato

Così…per chiarezza.

Fonti: Concurrent Programming on Windows( Joe Duffy)

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

Multithreading | Parallel Programming | Concurrent Programming

Cosa si intende per Memory Model?

by Marco 1. settembre 2009 17.03

Se vi è per caso capitato di approfondire, per qualche motivo, tematiche legate all’implementazione di soluzioni che fanno uso di codice parallelo/multithread/sincronizzazione probabilmente avete finito leggendo che vi è la possibilità di aumentare le performance usando tecniche di sincronizzazione “lock free”, ovvero senza ricorrere alle primitive di sincronizzazione messe a disposizione dal sistema operativo(che consumano risorse e vanno usate con attenzione).

Molto probabilmente qualche riga sotto l’espressione “lock free” avrete sicuramente trovato che tutto questo è possibile grazie al “Memory consistency model” (anche detto semplicemente memory model) implementato dall’hardware su cui il vostro codice gira.

Ma cos’è il memory model ?Perchè è importante conoscerlo ?

Per spiegarlo facciamo un passo indietro. Quando noi scriviamo codice sorgente ci immaginiamo che l’esecuzione dello stesso sarà così come l’abbiamo scritta. Purtroppo nei moderni processori non è così, nel senso che l’esecuzione del codice macchina potrebbe risultare diversa da quella da noi pensata anche senza inficiare il corretto funzionamento dei nostri algoritmi.

Le motivazioni principali sono:

1)I compilatori ottimizzano (Jit compiler compreso) il codice, spostando (code motion),cancellando, aggiungendo istruzioni per renderne più performante l’esecuzione.
2)I processori impiegano tecniche di “instruction level parallelism” (ILP) permettendo la parallelizzazione delle istruzione così da ridurre i cicli di clock totali.
3)I processori fanno uso di cache locali per velocizzare la scrittura (stores) e lettura (loads) delle locazioni di memoria, in sistemi multiprocessore la sincronizzazione tra le varie cache può portare ad uno spostamento delle istruzioni(cache coherency).

Tutto questo passa sotto il nome di instruction reordering.

Chi scrive codice a basso livello o compilatori o codice lock free, deve conoscere molto bene questi comportamenti per poter effettuare ottimizzazioni e far funzionare come si deve il codice (cioè come noi lo abbiamo scritto o senza provocare race condition).

Per concludere il memory model specifica precisamente quali tipi di scritture (stores) e letture (loads) possono essere spostate (o riordinate), in quali circostanze e come vengono spostate l’una rispetto all’altra.

I memory model si dividono tra weak (deboli) o strong (forti). Un “weak memory model” permette il riordinamento delle letture/scritture, un “strong memory model” (sequential consistency) proibisce tale riordinamento. Molti sistemi come quelli dal quale sto scrivendo questo post (architettura Intel x86) e la maggior parte dei sistemi sul quale Windows gira utilizzano un “weak memory model”.

Fonti: Concurrent Programming on Windows (Joe Duffy)

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Multithreading | Parallel Programming | Concurrent Programming

STM.NET io voto si :-)

by Marco 27. agosto 2009 15.02

Segnalo un nuovo interessante progetto pubblicato dai DevLabs chiamato Software Transactional Memory.

Il progetto è nato con l’intento di fornire un modo “semplice” per permettere ad uno sviluppatore di dichiarare che l’esecuzione di una parte di codice debba essere eseguita in modo “atomico” e “transazionale”.

I problemi che questa nuova features risolverebbe non sono pochi e di semplice soluzione per uno sviluppatore che si appresta a scrivere codice parallelo.

Fino ad oggi se noi vogliamo sfruttare il parallelismo nel nostro codice, dobbiamo fare molta attenzione agli “stati condivisi” e all’ ”invarianza” che precluderebbero il buon funzionamento dei nostri algoritmi.

Oggi per fare questo ci possiamo affidare a delle tecniche di locking come ad esempio un bel Monitor, es(il codice è al minimo per chiarezza e non tiene conto di eventuali stati di errore che potrebbero portare a lock orfani, deadlock etc…):

Monitor.Enter(obj);

…//codice atomico

Monitor.Exit(obj);

Il codice non è complesso, ma come ho indicato tra parentesi i problemi che possono nascere sono molti e non così semplici e scontati da anticipare. Inoltre il nostro bel monitor(l’oggetto obj) deve essere trattato con cura onde evitare ulteriori danni(deadlock per esempio).

Come se non bastasse, il secondo problema non è legato al parallelismo di per sè, ma dalla parte di codice che sta tra l’Enter e l’Exit(critical region). In caso il codice al suo interno vada in errore potrebbe succedere che venga meno l’invarianza, cioè che il sucessivo thread che entra in quella regione atomica trovi stati logici inconsistenti precludento il corretto funzionamento del codice, es(il codice non è completo…fate finta che sia correttamente inserito in un try…catch):

Monitor.Enter(obj);

Decimal saldoConto = corrente – addebito;

//quì ad esempio potrebbe scatenarsi un’eccezzione che invalida le righe di codice sopra

Monitor.Exit(obj);

Come potete vedere questo errore è di una gravità mostruosa(sempre che non siate molto ricchi :-D) e solitamente prima di effettuare le operazioni servirebbe del codice che controlla che tutto sia coerente, ma questo non è sempre facile e dipende dalla problematica, che può essere molto complessa con molte casistiche da verificare.

Quello che STM potrebbe risolvere in modo stra-elegante sono proprio queste due problematiche, tutto con un nuovo semplice metodo(con il proprio statement shortcut) e una modifica al funzionamento del Jitter(quindi un framework con delle modifiche interne) es:

Atomic.Do(()=> { <statememts> });

o

atomic { <statememts> }

In questo modo non dobbiamo preoccuparti di trattare bene il nostro monitor(il rifermento all’oggetto obj del metodo Enter), ma la cosa più furba è il fatto che un errore nel blocco causa il rollback di tutte le modifiche fatte in quello scope mantenendo così l’invarianza senza dover fare controlli.

Vi lascio con un esempio preso dalla guida che rende tutto molto più chiaro:

class BankAccount
{
        private int m_balance;
        public void ModifyBalance(int amount) {
       atomic {
                       m_balance = m_balance + amount;
                       if (m_balance < 0)
                               throw new OverdraftException(m_balance, amount);
                  }
        }
}

Spettacolo!!!

Spero vivamente che il progetto non vada nel dimenticatoio, sarebbe una manna per tutti noi.

Qui trovate il portale del progetto.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net | Multithreading | Parallel Programming | Concurrent Programming

File-less Activation WCF 4.0…RESTful style

by Marco 27. agosto 2009 13.15

A marzo avevo scritto questo blogin relazione al fatto che un’applicazione RESTful scritta con WCF aveva il difetto che gli URL erano “sporcati” dall’estensione “.svc” richiesta dall’infrastruttura di attivazione.

Ora nel framework 4.0, WCF ha sistemato questo problema con la possibilità di definire un “virtual service activation endpoint”  potendo così attivare servizi senza avere per forza bisogno di un file svc.

Tutto questo chiaramente per un miglior supporto alla programmazione RESTful.

Vi lascio il link con una spiegazione più dettagliata di come si dovrebbe fare(è una beta1), la sezione è intitolata “File-less Activation (no .svc)”.

Buona lettura.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.Net | Wcf

“Posso sapere quando il Garbage Collector parte?”

by Marco 18. agosto 2009 11.58

Con la versione .NET 3.5 SP1 è possibile sapere quando il garbage collector reclama memoria, vi lascio un post in cui è spiegato molto bene come funziona questa API con i limiti del caso.

Buona lettura.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.Net

“Saving changes is not permitted…” SQL Server Management Studio

by Marco 30. luglio 2009 16.27

Se vi capita di modicare la struttura di una tabella attraverso il SQL Server Management Studio di SQL Server 2008 potreste incappare in una finestra di questo tipo:

PC1

il messaggio vi dice che la modifica che state apportando richiederà di cancellare e ricreare la tabella(almeno questa è la modalità con cui il SQL Management Studio funziona riguardo a questi tipi di modifiche) e vi suggerisce in caso vi vada bene questa modalità di modifica, di disabilitare l’opzione chiamata “Prevent saving changes that require table to be re-created”.

L’opzione si trova sotto al menù Tool->Options->Designers

PS

Il Management Studio di solito crea una tabella temporanea con la nuova struttura, carica al suo interno tutti i dati della tabella da modificare e poi cancella la tabella vecchia e rinomina la temporanea. Se questa modalità non vi piace potete sempre ricorrere a degli ALTER a manina.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

SQL Server

C# 4.0

by Marco 29. luglio 2009 18.00

Tempo di vacanze, a chi non sapesse cosa fare in queste afose e calde giornate consiglio la visione di questo webcast sulle nuove features di C# 4.0(ce lo troveremo nel .Net Framework 4.0).

Riassumendo:

-Dynamic Typing : un nuovo insieme di classi all’interno del framework 4.0(chiamato Dynamic Language Runtime o DLR) che ci permette di rendere più “dynamic” la scrittura e l’esecuzione del nostro codice, esempio pratico:

dynamic variabile = 7;

variabile.Metodo();

il compilatore non si lamenterà più del fatto che Metodo() non appartiene alla classe Int32(il valore 7), ma verranno compilate per noi un’insieme di istruzioni(creazioni di classi e chiamate a metodi del runtime DLR, la keyword dynamic dichiara che variabile è un tipo dynamic) che descrivono quale metodo dovrà essere chiamato a runtime e su quale istanza(sollevando un’eccezione in caso il metodo non esista, funziona anche con le proprietà chiaramente). Per vederne una prima potenzialità, vi consiglio questo webcastdove il dynamic typing aiuta a scrivere codice più dichiarativo per leggere un file xml con la classe XElement e XmlNode. Il Dynamic Typing diventa molto utile nell’interoperabilità con COM permettendoci di scrivere codice più compatto,chiaro e con meno errori.

-Optional Parameter : così come fanno gli sviluppatori Visual Basic, ora anche in C# sarà possibile specificare dei parametri opzionali per i metodi e in fase di invocazione specificare un ordine diverso da quello posizionale basandosi sul nome ti tale parametro, esempio:

public class OP

{

         public void Metodo(int a = 3,string b = “default”){…}

}

….

Op variabile = new OP();

variabile.Metodo(); //legale verranno usati i default

variabile.Metodo(b : “ciao” , a : 5); //vengono specificati in modo nominale i parametri

variabile.Metodo(5);// a sarà 5 e per b verrà usato il default

-Covarianza e controvarianza : …esempio:

Date le classi

public class Animale
{

}
public class Giraffa : Animale
{

}

IEnumerable<Giraffa> giraffe = …

IEnumerable<Animale> animali = giraffe;

….

Le ultime 2 istruzioni avrebbero provocato un errore in compilazione con C# 3.0 cosa che è legale con C# 4.0 grazie alla covarianza. La covarianza e controvarianza sono disponibili per interfaccie e delegate generics con reference type. Il compilatore considera queste istruzioni “safe” grazie al fatto che nella creazione ad esempio dell’interfaccia, siamo noi(e per le interfaccie standard con IEnumerable<T> è già stato fatto nelle BCL)  attraverso delle nuove keywords in o out a decidere se queste conversioni sono legali o no, esempio dell’uso di out:

public interface IMyInterface<out T>
{
}

….

IMyInterface<Giraffa> giraffe = ….
IMyInterface<Animale> animali = giraffe ;

….

Se non avessi dichiarato con la keyword out l’argomento generico T il compilatore avrebbe sollevato un errore di compilazione.

Questa era solo una sintesi tutti questi argomenti nascondono un bel pò di materiale da studiarsi per benino con calma ;-)

Intanto vi lascio il linkal webcast e vi auguro una buona estate e delle buone vacanze(per chi ha la fortuna di farle come il sottoscritto :-D).

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

.Net

Perchè l’applicazione in debug è più lenta?

by Marco 24. giugno 2009 14.48

Vi lascio un post che spiega in dettaglio i motivi per cui un’applicazione che “gira” in debug(F5 con Visual Studio) è sensibilmente più lenta di una senza il debugger agganciato.

Ecco il link, buona lettura

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.Net | Windows

Validate user credentials with .NET 3.5

by Marco 23. giugno 2009 16.42

Recentemente mi è capitato di dover effettuare delle validazioni di login di utenti all’interno di un dominio, per fare questo ho utilizzato le classi  “Directory Services” di .NET 3.5(System.DirectoryServices.AccountManagement.dll).

Lo snippet di codice C# è davvero semplice:

using System.DirectoryServices.AccountManagement;

bool valid = new PrincipalContext(ContextType.Domain, "machine name/ip")
                  .ValidateCredentials(“userName”,”password”,ContextOptions.Negotiate);

logicamente il nome macchina, userName e password devono essere reali(spero che nessuno usi questa naming convention :-) ).

Lascio come riferimento l’articolo di MSDN Magazine che illustra tutte le potenzialità di questa API(fanno molto di più che validare la user name e la password di un utente).

Fonti: http://msdn.microsoft.com/en-us/magazine/cc135979.aspx

Correntemente valutato 5.0 da 1 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net

.NET ThreadPool 4.0(Beta 1)

by Marco 19. giugno 2009 15.00

La necessità di dover introdurre il concetto di “programmazione parallela” in modo più semplice possibile nelle menti di noi sviluppatori a causa dell’annuciato tramonto della famosa prima legge di Moore, ha portato il team del CLR a dover effettuare delle sostaziali modifiche nel funzionamento del ThreadPool che ci troveremo nel framework 4.0.

Le principali modifiche apportate sono le seguenti:

-Il ThreadPool funziona come una coda di workItem che vengono schedulati on demand, fino ad oggi la coda è stata implementata come una semplice linked list protetta da un Monitor. Questa tecnica diventa poco efficiente in caso di molti workload brevi, dovuti alla sincronizzazione della coda, inoltre il garbage collector è molto dispendioso nello scorrere questo tipo di struttura e liberarla in caso di necessità. Nel nuovo ThreadPool la coda è implementata con dei “chunk”(array) di workItem collegati. Questa tecnica permette di abbassare il lock necessari all’inserimento dei workItem(è necessario solo un’operazione atomica per incrementare l’indice nell’array) e permette al garbage collector di essere più efficente nella fase di collect.

-La modalità di scheduling utilizzerà l’algoritmo di “working stealing queue”, un meccanismo che permette di abbassare drasticamente il bisogno di lock e di mantere al massimo il consumo di CPU migliorando le prestazione complessive

-miglioria della funzionalità di “thread injection” che permette di regolare il numero di thread in gioco in modo dinamico così da utilizzare tutta la CPU disponibile

Alcune di queste features sono nate dalla stretta collaborazione con il PFX team(Parallel Framework Team) che fa largo uso di queste tecniche per ottimizzare il parallelismo all’interno delle Task Parallel Library.

Tutti questi nuovi meccanismi potete provarli nella Beta 1 di Visual Studio 2010 con il Framework 4.0 scaribili qui.

Vi lascio alcuni interessanti post e video sull’argomento

Daniel Moth post
Eric Eilebrecht post
Channel 9 video con Eric Eilebrech
Joe Duffy post

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

.Net | Multithreading

Bye Bye System.Data.OracleClient

by Marco 19. giugno 2009 10.13

Ve la riporto paro paro:

“The Decision

After carefully considering all the options and talking to our customers, partners, and MVPs it was decided to deprecate OracleClient as a part of our ADO.NET roadmap

We strongly recommend customers to use  our partners’ ADO.NET Provider for Oracle  instead of continuing to use Microsoft’s OracleClient for new application development”

…però…

Fonte:http://blogs.msdn.com/adonet/archive/2009/06/15/system-data-oracleclient-update.aspx

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net

“The process cannot access the file because it is being used by another process”

by Marco 17. giugno 2009 13.50

Parlando con il mio collega Fabioriguardo un progetto che sta seguendo, abbiamo convenuto che sarebbe utile avere la possibilità di sapere se un file è in utilizzo da qualche processo, per permetterci di attendere che venga liberato per essere elaborato dalla nostra procedura.

Girando un pò in internet ho visto che la soluzione più gettonata è quella di mettere un bel(battuta) try{…}cath(IOException){…} e nel catch valutare il dafarsi.

Questa soluzione non mi piace principalmente per 3 motivi:

1)Usare le eccezioni per una cosa che potrebbe non essere una “eccezione” non mi sembra corretto, io sono della fazione che tratta le eccezioni come un evento inaspettato e non un modo per fare logiche di business.

2)Sollevare e gestire una eccezione è dispendioso e se c’è la possibilità preferisco evitare di pagare questo prezzo.

3)Spesso il tipo di eccezione non individua precisamente il problema dove sta, a meno che non facciamo del “parsing” su qualche proprietà di essa, in quanto un tipo di eccezione può raggruppare più tipo di errori.

Detto questo(attenzione ho detto non MI piace, tutto è opinabile, avete il mio contatto se volete che ne parliamo approfonditamente), ho deciso di cercare un modo più “pulito” per risolvere questo problema e sono arrivato alla soluzione che consiste nello scrivere un extension method alla classe System.IO.FileInfo che controlla attraverso l’utilizzo di una API(nello specifico CreateFile)del sistema operativo se il file in questione è utilizzato da qualche altro processo.

Il pattern di utilizzo è abbastanza semplice:

//Creo il FileInfo
var fileInfo = new FileInfo(path);
//Controllo se il file è usato
Console.WriteLine("File usato: {0}", fileInfo.IsUsingByAnotherProcess());

per poterlo utilizzare dobbiamo avere visibilità sulla classe FileInfoExtension che contiene l’extension method.

Questo metodo tuttavia non è perfetto, o meglio, soffre di “race condition” ovvero se tra la chiamata IsUsingByAnotherProcess() e l’apertura del file(per processarlo) qualcuno si mette in mezzo possiamo comunque prenderci una bella eccezione per file usato da un’altro processo, ma in quel caso possiamo correttamente gestire l’eccezione come meglio ci pare(quì si che non ci aspettavamo di trovarlo occupato di nuovo). Il caso più utile in cui questo metodo può essere usato è quando sappiamo che qualcuno potrebbe “usare” il file e poi tocca a noi…per esempio un upload di file e scheduled task che elabora il file, quì è chiaro che solo noi e l’upload possono usare il file e in ordine prevedibile. Nel caso questo non fosse il vostro caso potete gestirlo nel catch(IOException) ancora attraverso questo extension method così da essere certi che il problema sia ancora quello, riprovando succesivamente l’operazione.

Potete scaricare il codice di esempio FileInfoExtension.zip (40,61 kb)

Se qualcuno ha qualche idea migliore o qualcosa da aggiungere, prego!

------------------------

Ho mandato un feedback a microsoft sulla problematica, ma dicono che non hanno pianificato di aggiungerlo nella versione 4.0 e che qualcun altro aveva già sottolineato una mancanza in questa api, lascio il link del feedback http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=468166 , magari in una versione futura fanno qualcosa.

Correntemente valutato 5.0 da 1 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

.Net | Windows

.NET 4.0 Cancellation Framework, ottima idea

by Marco 16. giugno 2009 11.37

Capita non di rado in alcune applicazioni di avere la possibilità di interrompere qualche operazione “lunga” o “asincrona” a fronte della richiesta di qualche operatore sia esso un’utente comune o un agente software. Questa operazione spesso sottovalutata dovrebbe essere conclusa senza portare il sistema in uno stato inconsistente in tutti i sensi, per tutti i sensi intendo sia dal punto di vista “tecnico”(es:stabilità del processo, risorse etc..), sia dal punto di vista dello stato dei dati in questione(es:una griglia su un form).

Questo significa che qualunque sia il tipo di operazione da interrompere, questa deve essere conscia del fatto che qualcuno ha deciso che deve smettere di fare quello che sta facendo senza provocare danni.

Con questo problema si sono dovuti scontrare chiaramente il team delle Task Parallel Library(.NET 4.0), riguardo al problema di dover interrompere un’operazione asincrona/parallela.

A fronte di questo hanno deciso di creare un’insieme di classi preposte alla gestione delle “cancellazioni” di operazioni in modo “cooperativo”, tutto questo sotto il nome di  “Cancellation Framework”.

Le classi principali che compongono questo framework sono: CancellationToken che verrà passata all’operazione “interrompibile” per informarla che qualcuno ha richiesto uno stop, e CancellationTokenSource che scatenerà l’interruzione.

La cosa molto interessante è la modalità di comunicazione tra CancellationTokenSource e CancellationTokens (potrebbero essere più di uno, potremmo richiedere lo stop a più operazioni asincrone/parallele contemporaneamente). Possiamo effettuare un polling sulla proprietà IsCancellationRequested dell’oggeto CancellationToken o registrare una callback che verrà eseguita alla richiesta della cancellazione.

Questi tipi di pattern sono già stati implementati in molte classi del framework, ma ogni implementazione ha sempre avuto un suo set di classi personalizzate. L’idea di avere un framework comune mi sembra ottima, sarebbe molto più facile scrivere codice più “generico” e adattabile a contesti diversi, oltre che corretto nella sua implementazione (ci sono molte cose non banali da gestire, la sincronizzazione etc…).

Per una più dettagliata spiegazione dell’argomento vi lascio il post del pfxTeam.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net | Multithreading | Parallel Programming

Parallel.For/ForEach e i System.Threading.Task

by Marco 9. giugno 2009 14.08

Il concetto che per avere migliori performance dobbiamo usare meno thread fisici possibili e di conseguenza meno risorse( magari 1 thread per core ), viene usato anche all’interno delle nuove Task Parallel Library ( .NET Framework 4.0 ) riguardo agli oggetti Task.

Cio significa che se abbiamo un ciclo for parallelo ( Parallel.For/ForEach ), non è detto che per ogni iterazione avremo un’oggetto Task che verrà schedulato, ma l’odierna implementazione prevede che ogni Task processi un chunk di operazioni ( iterazioni diciamo ), così da abbassare l’overhead della creazione e gestione degli stessi.

Ciò potrebbe portare a subdoli problemi, come nel caso in cui ci siano delle dipendenze tra le iterazioni che potrebbero mandare in deadlock il loop.

Se vi interessa un’approfondimento sulla tematica vi consiglio di dare una letta a questo post del pfxTeam :

http://blogs.msdn.com/pfxteam/archive/2009/05/26/9641563.aspx

Generare una serie di date con T-SQL

by Marco 4. giugno 2009 14.36

Per un progetto su cui sto lavorando ho bisogno di avere tutti i giorni di un dato mese passando come parametri l’anno e il mese.

Dopo aver preso spunto dall’idea di Itzik Ben-Gan dal suo libro “Inside SQL Server 2005 T-SQL Programming” sono arrivato a questa soluzione( è la bozza diciamo ).

set dateformat ymd
declare @year int,@month int
set @year = 2009
set @month = 6
;with
    L0 as (select 1 as c union all select 1 ),
    L1 as (select 1 as c from L0 as A,L0 as B),
    L2 as (select 1 as c from L1 as A,L1 as B),
    L3 as (select 1 as c from L2 as A,L2 as B),
    L4 as (select 1 as c from L3 as A,L3 as B),
    L5 as (select 1 as c from L4 as A,L4 B),
    Nums as (select row_number() over(order by c) as n from L5)
select CAST(    CAST(@year as nvarchar(4))  + N'-' +
                CAST(@month as nvarchar(2)) +N'-' +
                CAST( n  as nvarchar(2)) as datetime) as dt 
from Nums where n <= 31 and
                ISDATE(CAST(@year as nvarchar(4))  + N'-' +
                CAST(@month as nvarchar(2)) +N'-' +
                CAST( n  as nvarchar(2))) = 1

Questa query ritorna il set di date del mese di giugno dell’anno 2009.
Lo script fa uso delle CTE, funzioni di Ranking e funzioni sulle date. Funziona con le versioni di SQL Server che supportano queste features, io la sto usando su SQL Server 2005.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

SQL Server

Prevenire le System.OutOfMemoryException

by Marco 14. maggio 2009 12.32

Nell'ultimo progetto che ho sviluppato che comprendeva la creazione di un AppDomain per il caricamento "on the fly" di Assembly da un database e la notifica ai client dello stato delle operazioni attraverso una callback di WCF sono incappato in una problematica documentata del funzionamento del GC (documentazione http://msdn.microsoft.com/en-us/magazine/cc163491.aspx , problema legato alla frammentazione e alle chiamate remote, paragrafo "Unneeded rooted reference" ) che in certi casi particolari mandava il mio servizio in "out of memory".

Dopo aver verificato questo comportamento attraverso il CLR Profiler e non potendo riscrivere completamente quella parte ho cercato un modo per poter controllare il caso in cui l'operazione che avrei dovuto eseguire sarebbe andata in "out of memory" per poterla prevenire. Dopo alcune ricerche ho trovato la classe che faceva al caso mio. La classe in questione è la System.Runtime.MemoryFailPoint .
Questa classe permette di capire se sono disponibili n Mb di ram, in caso negativo verrà sollevata una eccezione di tipo System.InsufficientMemoryException che potremmo gestire magari liberando la memoria in qualche modo.
L'utilizzo della classe è molto semplice basta instanziarla e passare al costruttore i Mb che sono richiesti.

Attraverso l'utilizzo della classe sopracitata sono così riuscito a gestire il problema testando a runtime lo stato della memoria e "reciclando" l'appDomain ho così controllato il consumo evitando la System.OutOfMemoryException.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.Net

“Axum” e il parallelismo implicito

by Marco 11. maggio 2009 16.13

Dai laboratori di ricerca di Microsoft è nato il progetto “Axum”, un’idea ambiziosa e molto interessante nata con lo scopo di permettere a noi sviluppatori di scrivere codice lasciando che il runtime possa “capire” e parallelizzare in modo autonomo l’esecuzione dello stesso, attraverso un linguaggio che si basa sull'architettura Web e sul principio dell'isolamento(fondamentale nella programmazione parallela).

Vi consiglio di dare un’occhiata al video che trovate nella pagina principale di presentazione del progetto al link http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx

Credo che il “parallelismo implicito” sia l’unico modo per permettere a tutti di sfruttare veramente la potenza che i multicore ci mettono a disposizione senza dover leggere troppi libri :-)

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Multithreading | Parallel Programming

VMMap un nuovo tool da Sysinternals per analizzare la memoria consumata da un processo

by Marco 23. marzo 2009 16.21


Per chi se lo fosse perso vi comunico che Sysinternals(Mark Russinovich e Bryce Cogswell), ha aggiunto ai propri tools di analisi del sistema operativo una nuova utility, si chiama VMMap e permette di avere il dettaglio sulla tipologia della memoria consumata da un processo su una macchina Windows.

L'ennesimo tool di inestimabile valore per chi fa throubleshooting sulle piattaforme Windows.

Vi lascio il link del tool http://technet.microsoft.com/sysinternals/dd535533.aspx

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Windows

Togliere l’estensione .svc dall’URI in un servizio REST con WCF

by Marco 17. marzo 2009 17.07

Una delle caratteristiche principali dell'architettura "REST style" consiste nel fatto che ogni risorsa sulla quale possiamo effettuare delle operazioni (HTTP verbs) viene univocamente identificata attraverso una URI. Avere delle URIs “ben progettate” diventa quindi molto importante.

Quando creiamo un servizio REST con WCF ci rendiamo conto che le URIs che ne risultano potrebbero essere “disturbate” dall’estensione .svc, la quale permette all’infrastruttura IIS/ASP.NET di processare correttamente le richieste.

Le URIs risultanti sono simili a questa: http://www.domain.com/ServiceName.svc/Resource
Le URIs che noi vorremmo poter utilizzare dovrebbero essere invece strutturate in questo modo : http://www.domain.com/ServiceName/Resource

Come fare in modo che il tutto funzioni con le URIs "REST style"?

Una delle strade possibili consiste nello scrivere un HttpModule che ci permetterà di mappare l'URI "REST style" con l'URI originaria(con l'estensione .svc). Per implementare questa tecnica di url rewrite, dobbiamo creare una classe che implementi l'interfaccia IHttpModule che consta di 2 metodi Init e Dispose. Nel metodo Init ci viene passato dall'infrastruttura di ASP.NET l'oggetto HttpApplication che utilizzeremo per abbonarci all'evento BeginRequest, nel quale gestore attraverso uno degli overload del metodo RewritePath dell'oggetto di contesto HttpContext (HttpContext.Current) possiamo eseguire il "re-write" dell'URI "REST style" all' URI originaria, utilizzata dall'infrastruttura di IIS/ASP.NET/WCF per attivare l'oggetto che implementa la logica del nostro servizio.
Una volta scritto il nostro HttpModule, basterà registrare lo stesso nella sezione <httpModules> della configurazione di ASP.NET.

Chiaramente rimuovere l’estensione .svc rende la URI molto più “elegante” e “significativa”. Utilizzare una URI “non-elegante” non va comunque contro i principi fondamentali dell'architettura "REST style", però qualche purista potrebbe storcere il naso :-) .

Se a qualcuno interessa una implementazione dell'HttpModule fatemelo sapere che ve la mando o la pubblico.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Wcf

“…se hai il pc lento è perchè hai poca ram…”(Parte 2)

by Marco 18. febbraio 2009 10.17

(...continua da http://www.marcorossignoli.it/post/se-hai-il-pc-lento-e-perche-hai-poca-ram(Parte-1).aspx)

…quando un programma vuole allocare della memoria per poi utilizzarla deve prima o poi richiederla al sistema operativo attraverso delle API come ad esempio VirtualAlloc.
Quando parlo di programma, non intendo solamente il codice che noi scriviamo, ma anche ad esempio un qualsiasi runtime che effettua questa chiamata per noi.
Ad esempio il runtime .NET effettua questa operazione quando noi facciamo le new() sugli oggetti, ma fortunatamente tutta questa complessità ci è nascosta e la gestione della memoria viene fatta in modo trasparente dal garbage collector.
Per capire un pò meglio come funziona il tutto, scriviamo un pò di codice C#, precisamente una bella console application che farà in modo esplicito una richiesta di memoria virtuale al sistema operativo.

Intanto con un pò di P/Invoke permettiamo a CLR di chiamare l’API (vi consiglio questo tool per generare le firme in .NET Invoke Interop Assistant):

static class Native         
{        
      public const int MEM_RESERVE = 8192;        
      public const int PAGE_READWRITE = 4;        
      public const int MEM_COMMIT = 4096;        

      [System.Runtime.InteropServices.DllImportAttribute
        ("kernel32.dll",EntryPoint ="VirtualAlloc",SetLastError=true)]        
      public static extern System.IntPtr VirtualAlloc(
            [System.Runtime.InteropServices.InAttribute()] System.IntPtr lpAddress,
            uint dwSize,
            uint flAllocationType,
            uint flProtect);

}

 

Attraverso VirtualAlloc possiamo così richiedere memoria (virtuale, ricordiamoci che noi possiamo usare solo quella) al sistema operativo che poi utilizzeremo per fare qualcosa, come ad esempio metterci le nostre strutture dati. E adesso il main:

       static void Main(string[] args)
       {
           uint Megabyte = 1048576;           

           IntPtr memoryPointer = IntPtr.Zero;

           memoryPointer = Native.VirtualAlloc(memoryPointer,
                                                  Megabyte * 300,
                                                  Native.MEM_RESERVE,
                                                  Native.PAGE_READWRITE);

           if (memoryPointer == IntPtr.Zero )
               throw new Win32Exception();

           Console.ReadKey();
       }

Il codice richiede semplicemente 300 megabyte di memoria virtuale sulla quale il processo possa scrivere e leggere.
In caso l’API ritorni null (IntPtr.Zero) significa che non c’è sufficiente memoria e l’allocazione non è andata a buon fine (ad esempio se noi mettiamo 3000 invece che 300 l’API ci risponde picche in quanto abbiamo visto che lo spazio di indirizzamento di default per lo user mode è di 2GB quindi non è possibile fare un’allocazione superiore a quella).

Se guardiamo bene il codice ci accorgiamo che l’API ci richiede un parametro particolare nel quale io ho passato MEM_RESERVE, questo significa che il sistema operativo non mi mette a disposizione subito 300 megabyte di ram fisica, ma semplicemente richiedo che mi vengano riservati 300 megabyte dello spazio di indirizzamento che succesivamente renderò fisici richiedendolo attraverso la stessa api, ma passando il parametro MEM_COMMIT. Riservarsi memoria virtuale non significa che posso metterci qualcosa, ma semplicemente mi permette di creare un blocco di memoria e avere la sicurezza che quando ne farò il commit (quindi verrà fisicamente messa a disposizione) avrò un insieme di locazioni contigue in memoria, nelle quali potrò mettere quello che mi serve.

Detto questo si capisce che abbiamo 2 tipi memoria nel nostro processo, la memoria virtuale e la memoria fisica effettivamente utilizzabile, tecnicamente chiamata “committed memory” alla quale mi riferirò sempre attraverso indirizzi virtuali. Quindi la memoria effettiva consumata dal mio processo non è quella virtuale ma quella committed ovvero quella che è stata effettivamente mappata ad indirizzi fisici.
Per provare questo comportamento possiamo fare un test e verificare che riservare memoria virtuale non consuma effetivamente la memoria fisica del sistema. Per effettuare questo test dovete scaricarvi un tool Process Explorer di Mark Russinovich, un architetto del core di Windows che lavora nel team di microsoft e co-autore del libro che vi ho segnalato come fonte.
A questo punto eseguiamo il codice che segue e guardiamo un pò di numeri:

1 static void Main(string[] args)
2         {
3            uint Megabyte = 1048576;           

4            IntPtr memoryPointer = IntPtr.Zero;

5            memoryPointer = Native.VirtualAlloc(memoryPointer,
                                                    Megabyte * 300,
                                                    Native.MEM_RESERVE,
                                                    Native.PAGE_READWRITE);

6            if (memoryPointer == IntPtr.Zero )
                 throw new Win32Exception();

7           memoryPointer = Native.VirtualAlloc(memoryPointer,
                                                   Megabyte * 300,
                                                   Native.MEM_COMMIT,
                                                   Native.PAGE_READWRITE);

8            Console.ReadKey();
9        }


Tanto per cominciare vediamo a quanto ammonta la committed memory nel mio sistema nel momento in cui scrivo. Per vederla ho cliccato sull’icona  icona  nella barra sotto il menù classico.
Ecco i risultati:

  info

Circa 2.9 di memoria fisica allocata. Nel riquadro Commit Charge vediamo le stime meno approssimative.

Ora facciamo partire il nostro programma…mettiamo un bel breakpoint alla riga numero 6 e vediamo lo stato della memoria:

infoVirtual

come possiamo notare è cambiato poco niente…un pò di committed in più ma poca roba (qualcosa ha dovuto caricare, alla fine un processo in più in memoria c’è e fino al breakpoint ci siamo arrivati, da qualche parte quei byte li dobbiamo mettere). Quindi possiamo affermare che allocare memoria virtuale non consuma memoria fisica effettiva.

Ora mettiamo un’altro breakpoint alla riga 8 e vediamo:

InfoCommited

come possiamo vedere ora stiamo consumando circa 300 megabyte di memoria fisica (committed memory) in più (non sono precisamente 300 ma un pò di più…ma sul mio pc girano molti processi e quello è un counter globale, chissà quale altro processo ha richiesto qualcosa :-) ). Quindi possiamo affermare una volta per tutte che la memoria virtuale non è la memoria realmente utilizzata.

Vediamo ora il consumo di memoria dalla prospettiva del nostro processo. Per fare questo dovete impostare un paio di contatori utili. Andate sul menù View->Select Columns->Process Memory e fleggate Private Bytes e Virtual Size.
Il contatore Private Bytes tiene conto della committed memory consumata dal processo, mentre Virtual Size è semplicemente la memoria virtuale riservata per quel processo. Attenzione quello che ho scritto non è propriamente vero o meglio è impreciso, un processo può consumare memoria fisica privatamente (Private Bytes), ma potrebbe anche consumare memoria fisica attraverso l’utilizzo delle “page file backed section” che sono delle zone di committed memory condivise con altri processi(vengono chiamate così in quanto possono essere scritte sul file di paging se serve, vedi section objects) che non vengono conteggiate nel counter di un processo.

Passiamo ai numeri:

le colonne sono rispettivamente PID (id del processo) Virtual Size e Private Byte

Riga 6

Process1

Riga 8

Process2

Ancora una volta possiamo notare la differenza tra memoria virtuale e committed memory (memoria fisica allocata).

Quindi diciamo che la somma di tutta la committed memory di tutti i processi che girano nel nostro sistema ci da più o meno la stima di quanta RAM ci serve…(anche quì ho omesso le “page file backed section” e qualche altro dettaglio per semplicità).

Un ultimo cenno aspetta al paging file; in caso la memoria fisica fosse troppo poca per far girare i nostri programmi, windows può avvalersi del disco fisso come storage temporaneo, permettendoci così di aumentare il “commit limit” del nostro pc. Chiaramente il codice e i dati di un programma devono essere in RAM per essere utilizzati quindi sarà compito del sistema operativo usare policy di “caricamento” e “scaricamento” sul file di paging delle pagine di memoria meno utili. Perciò aumentare il file di pagin significa semplicemente avere più committed memory disponibile, certo se per esempio (esagerato ma è per rendere l’idea) abbiamo 2GB di ram e abbiamo bisogno di 6GB di page file per non andare in out of memory significa che la nostra attività consuma mediamente 4 volte la ram fisica che ho (2GB fisica + 6GB file di paging) e in questo modo l’attività di paging (scrivere sul file di paging e leggere da esso) potrebbe peggiorare seriamente le prestazioni della macchina. Quindi non esiste una formula assoluta per dimensionare il file di pagin, ma possiamo controllare il nostro utilizzo medio per esempio guardando per un periodo alla sera prima di andare a casa il contatore Peak (riquadro Commit Charge) con Process Explorer (vedi sopra) e fare la differenza con il contatore Total (riquadro Physical Memory) così da vedere di quanta memoria in più abbiamo mediamente bisogno, impostando il file di paging intorno a quel numero.

Spero con questi 2 blog di aver chiarito meglio il motivo per cui, se il pc è lento, non è sempre colpa della RAM, ma per saperlo con certezza servono come sempre i numeri…l’idea di questo post mi è venuta quando l’azienda che mi fa l’hosting di un server fisico mi ha consigliato di aumentare la ram se volevo passare da Sql Server 2005 a Sql Server 2008, ho risposto che per ora i numeri non mi dicono che serve un upgrade di RAM ;-)

…chissà se l’indovino aveva ragione…

Fonti: http://www.microsoft.com/learning/en/us/Books/6710.aspx

Correntemente valutato 5.0 da 2 utenti

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Windows

“…se hai il pc lento è perchè hai poca ram…”(Parte 1)

by Marco 17. febbraio 2009 15.17

Il titolo del blog è volutamente provocatorio (anche se questa frase la sento spesso da persone tecniche e non), almeno che chi ha detto quella frase non sia un mago o un indovino e cercherò di chiarirlo in questo post e nei seguenti.

Quando lanciamo un programma più volgarmente detto “un exe” o “eseguibile”, generalmente usiamo direttamente o indirettamente una delle APIs forniteci dal sistema operativo le quali iniziano solitamente con ‘CreateProcess…’( http://msdn.microsoft.com/en-us/library/ms682425.aspx )
Creare un processo vuol dire tra le altre cose mettere a disposizione del nostro “exe” un insieme di indirizzi di memoria dove il codice del programma possa essere caricato ed eseguito (dalla CPU) e dove i dati gestiti dallo stesso possano essere immagazzinati e usati.
Il nostro programma farà inoltre utilizzo di determinati servizi messi a disposizione del sistema operativo come ad esempio una finestra o un file, il che comporta che lo stesso SO debba mettere da qualche parte le varie strutture di memoria che gli permettono di funzionare (drivers e varie parti del so stesso…etc…).
Tutta questa memoria per essere correttamente utilizzata dal processore deve essere chiaramente nella famosa memoria chiamata RAM.
Detto questo, abbiamo capito che un programma per funzionare, deve usare della memoria allocata dal processo stesso (l’ ‘exe’ lanciato) e un’altra parte di memoria già esistente e gestita dal sistema operativo. Per evitare che chi scrive programmi possa rendere il sistema instabile andando ad esempio a scrivere sulla memoria gestita dal sistema operativo, il sistema stesso con l’aiuto dell’hardware protegge le sue locazioni dall’accesso “non legale” attraverso il concetto di “user mode” e “kernel mode”. Quando il programma  “gira” in “user mode” significa che ha accesso solo alla parte di indirizzi che non sono gestiti dal sistema operativo e in caso venga toccato un indirizzo di questo tipo, il sistema operativo  stesso, con l’aiuto dell’hardware, solleva un’eccezione avvisando che il processo sta utilizzando una parte di memoria che in “user mode” non può toccare. Quando viene effettuata una chiamata ad una API del sistema operativo che fa utilizzo di risorse (memoria) che servono alla funzionalità stessa, con una particolare istruzione macchina, l’esecuzione del codice passa da “user mode” a “kernel mode” permettendo al codice (diciamo codice del sistema operativo…drivers, APIs etc…) di accedere a qualsiasi locazione di memoria disponibile. Quando l’API ha finito il lavoro per la quale è stata chiamata avviene il processo inverso, ovvero il codice ritorna a “girare” in “user mode”, così il nostro codice scritto “male” non può danneggiare la memoria “importante” evitandoci un bel pò di blue screen.
Ora il sistema operativo ci permette di eseguire più processi contemporaneamente (multitasking) quindi serve un modo per poter virtualizzare la memoria che un processo utilizza facendogli credere di aver a disposizione la sua parte della stessa e di poter diciamo chiamare delle APIs (del sistema operativo) che a sua volta useranno una parte di memoria a loro adibita. A questo scopo esiste proprio un tipo di memoria chiamata “memoria virtuale” , una sorta di interfaccia verso l’effettiva memoria…indirizzi relativi, ecco li potremmo definire così. Ogni volta che lanciamo un programma lo stesso è convinto di avere una memoria tutta per lui a cui si riferirà in modo virtuale, sarà poi compito del sistema operativo con la collaborazione dell’hardware tradurre quell’indirizzo virtuale in una cella di memeoria fisica. Per farvi un’idea un pò più reale dovreste immaginarvi la memoria come un array di byte, solo che se voi scrivete memoriaVirtuale[27] effettivamente state accedendo alla memoriaFisica(ram)[1434] (che a noi frega poco).

Tecnicamente parlando, per default Windows su un sistema x86 (senza particolari impostazioni che cambiano le cose, vedi PAE-Physical Address Extension) utilizza una struttura a 2 livelli per tradurre un indirizzo virtuale in un indirizzo fisico, un indirizzo a 32bit viene diviso in 3 componenti che sono indici che vengono usati nelle strutture che effettuano il mapping, 10bits per le "page directory index", 10bits per le "page table index" e 12bits come "byte index" per un totale di 32bits.

Questo meccanismo permette quindi al nostro programma di non dover sapere quanta memoria fisica è disponibile (magari molto meno di quella usata da tutti i processi insieme…mah potremmo buttarla sul disco fisso; sarà lento ma meglio che non far partire il programma…insomma la paginiamo e se serve la ricarichiamo e scarichiamo qualcosa d’altro che non è utilizzato) e inoltre possiamo far girare più processi completamente isolati tra loro (esclusa la parte di memoria del SO che tanto condividiamo, tanto le funzionalità messe a disposizione dal SO ai processi sono sempre quelle o no? Quella basta proteggerla dai programmi fatti male :-P cioè se memoriaVirtuale[1] magari memoriaFisica(ram)[23459] è del sistema operativo…ci prendiamo una bella eccezione, solo il codice che gira in kernel mode può usarla).

Per concludere questo primo post diciamo che ogni processo su una macchina a 32bit ha la propria memoria virtuale di 2^32; quindi 4GB divisi tra user mode e kerner mode in questo modo (per default, ma il layout potrebbe cambiare in caso di particolari impostazioni) :

                                                    image_thumb_12


Bene…prendete fiato…nel prossimo post continuiamo a cercare di capire se l’indovino è bravo o no :-)

Fonti: http://www.microsoft.com/learning/en/us/Books/6710.aspx

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Windows

In attesa delle TPL: Parallel.For me ;-)

by Marco 16. febbraio 2009 16.04

In attesa delle Task Parallel Library che saranno presenti nella versione 4.0 del Framework e che ora sono in CTP mi sono servito della sintassi che utilizzeremo in futuro per esprimere un ciclo For parallelo.

La firma di uno degli overload del For parallelo delle TPL ad oggi è questo:

public static void For(int fromInclusive,int toExclusive,Action<int> body)

Praticamente possiamo eseguire un’azione (Action<int> body) in parallelo più volte finchè la condizione fromInclusive < toExclusive viene verificata.

Il parametro di tipo intero che viene passato al body è l’indice del counter.

La sintassi con cui possiamo invocare il for parallelo è ad esempio questa:

System.Threading.Parallel.For(0,4,
               c =>
               {                                       
                   Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);                   
               });

il codice soprastante funziona se avete scaricato la CTP del giugno scorso e avete referenziato l’assembly System.Threading.
Il codice non fa niente di interessante al posto del Console.WriteLine(…) avreste dovuto mettere la parte di codice che volete venga eseguita in parallelo.

La mia versione del For parallelo fa uso della classe ThreadPool presente nel framework e che possiamo utilizzare già oggi, quindi utilizza un differente algoritmo di scheduling e non quello utilizzato dalle nuove TPL (molto più fine e complesso, magari vi spiegherò in qualche post futuro come funziona)…diciamo che hanno scritto qualche riga in più :-) e che risolvono molti più problemi di quelli che la mia classe risolve. Quindi il funzionamento beneficia delle gioie e soffre i dolori che il funzionamento della classe ThreadPool porta con se.

La classe che ho scritto e utilizzato è la seguente:

public class Parallel
{
    public static void For(int fromInclusive, int toExclusive, System.Action<int> body)
    {
        ThreadPool.QueueUserWorkItem(f =>
        {
            for (int i = fromInclusive; i < toExclusive; i++)
            {
                ThreadPool.QueueUserWorkItem(p =>
                    {
                        Data pl = (Data)p;
                        pl.Action(pl.Count);                   
                    }
                    , new Data() { Action = body, Count = i });
            }
        }, null);       
    }  
    class Data
    {
        public Action<int> Action { get; set; }
        public int Count { get; set; }
    }
}

Il codice di invocazione è il medesimo delle TPL basta evitare di usare la parte System.Threading, ma scrivere solamente:

Parallel.For(0,4,
               c =>
               {                                       
                   Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);                   
               });

la classe deve essere chiaramente visibile.
Il codice non è stato testato "seriamente" quindi potrebbe essere afflitto da bugs e non tratta problematiche come ad esempio gestione delle eccezioni, sospensione del task, sincronizzazione, partizionamento o altre problematiche legate al parallelismo che sono state gestite all’interno delle TPL…per il mio problema questa classe è più che sufficiente, il giorno che rilasceranno le TPL toglierò la mia classe e avrò bisogno solo di referenziare l’assembly con le nuove classi per sfruttare il lavoro del team di Microsoft.
Se trovate qualche bugs o questa soluzione non risolve il vostro problema o ne crea di nuovi contattatemi qui che magari ne parliamo.

 Scarica la solution di esempio

Essere architetti...

by Marco 16. febbraio 2009 09.46
Riporto un interessante blog di Joe Duffy (Task Parallel Library) sulla sua idea di "architetto software".

Tra tutte le sue interessanti opinioni, cito quella che ritengo più importante e che mi trova d'accordo:

"An architect’s success is measured by what he or she ships to customers, and not by the amazing ideas that were ultimately never realized."

Vi lascio il link del post: http://www.bluebytesoftware.com/blog/PermaLink,guid,727ecd54-2ccf-4fa0-a0e0-f27ee125f7ae.aspx

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Conoscere il tipo di binding da un [OperationContract] in WCF

by Marco 13. febbraio 2009 13.46

Un pò di tempo fa mi è stato chiesto se era possibile conoscere quale binding venisse utilizzato per il dispatch di una determinata Operation con WCF.
La soluzione più elegante IMHO è quella di utilizzare l'oggetto OperationContext che porta con se tutto il contesto di chiamata e ci permette di ispezionarne tutte le caratteristiche, comprese quelle del channel su cui è stata effettuata.
Precisamente per conoscere il tipo di binding possiamo affidarci alla proprietà Scheme del Listener che ha ricevuto la chiamata:

 OperationContext.Current.EndpointDispatcher.ChannelDispatcher.Listener.Uri.Scheme

la proprietà Scheme è di tipo string, ad esempio se stiamo ricevendo una chiamata su un binding di tipo http troveremo che la proprietà sarà "http".
Detto questo spetta a noi decidere dove controllare questa proprietà a seconda dell'utilizzo che ne vogliamo fare, potrebbe essere in uno dei tanti punti di estensione di WCF come direttamente nel corpo della chiamata al servizio (che non mi piace molto, ma dipende dal problema da risolvere)

Lascio lo snippet del codice completo creato con il tempate di VS 2008:

public class Service : IService

{

    public string GetScheme(){

                  return OperationContext.Current.EndpointDispatcher.ChannelDispatcher.Listener.Uri.Scheme; 

         }  

}

Ho chiaramente modificato il contratto.

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Wcf

Disclaimer
Le opinioni espresse in questo blog sono mie opinioni personali.

© Copyright 2010 Knowledge.CreateAsync()