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

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

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

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

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

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

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

© Copyright 2010 Knowledge.CreateAsync()