[EF] QueryCompilate e MergeOption


Per ottenere il massimo delle prestazioni quando si devono usare LINQ query è consigliato precompilarle e quando possibile usare anche l’opzione MergeOption.NoTracking. Quest’ultima evita di salvare le informazioni sulle modifiche degli oggetti nell’ObjectContext. E cosi’ ho fatto; ho compilate le query e le ho usate per leggere delle entità e modificarle. Ma ad un certo punto saltava fuori un errore sulla SaveChanges che non poteva essere eseguita poichè la query era stata compilata con l’opzione MergeOption.NoTracking.

Vediamo cosa era successo. Consideriamo il seguente codice che compila una query che ritorna un utente data la email. Poi ci sono due metodi che usano questa query; una che legge solamente il nome dell’utente e quindi viene preceduto dal NoTracking ed un secondo metodo che scrive il nome dell’utente e quindi implicitamente è preceduta da AppendOnly, il valore di default di MergeOption .

public class QueryCompiled 
{
  public static Func<MyEntities, string, IQueryable<Users>> GetUserByEmail = 
            CompiledQuery.Compile<MyEntities, string, IQueryable<Users>>( 
                                             (MyEntities ctx, string email) => 
                                             from a in ctx.Users 
                                             where a.Email == email 
                                             select a);
}
public class A
{
  public string GetUserName(string email)
  {
    using (MyEntities context = new MyEntities()) 
    {
      context.Users.MergeOption = MergeOption.NoTracking; 
      var users= (QueryCompiled.GetUserByEmail(context, email)); 
      return users.Name;
    }
  }
  public void SetUserName(string email, string name)
  {
    using (MyEntities context = new MyEntities()) 
    {
      var users= (QueryCompiled.GetUserByEmail(context, email)); 
      users.Name = name;
      context.SaveChanges();
    }
  }
}

Se l’ordine di esecuzione dei metodi della classe A è il seguente va tutto bene :

A classeA = new A();
classeA.SetUserName(“aaa@aaa.aa”, “pippo”);
classeA.GetUserName(“aaa@aaa.aa”);

Se l’ordine di esecuzione si inverte, come nel seguente caso, allora ottengo l’errore che dicevo prima :

A classeA = new A();
classeA.GetUserName(“aaa@aaa.aa”);
classeA.SetUserName(“aaa@aaa.aa”, “pippo”);

Il motivo è il seguente; quando la query compilata viene invocata la prima volta allora viene memorizzata in una chache una forma ottimizzata della query. Durante questa prima invocazione vengono memorizzate altre informazioni tra cui anche il tipo di MergeOption attivo nel momento dell’invocazione. Quest’ultimo è un particolare importante il cui dettaglio non avevo trovato nella documentazione ufficiale. Nel secondo caso indicato sopra succede che la prima volta viene invocata la query compilata con MergeOption.NoTracking e questo valore viene associato alla query compilata per cui quando dopo vado a richiamare la stessa query compilata per modificare un valore nel momento in cui si esegue SaveChanges la query fallisce perche’ risulta che è attivo il NoTracking. Notare che non cambia nulla se vado ad aggiungere un MergeOption.AppendOnly nel metodo SetUserName. Non cambia nulla anche se richiamo la query con un diverso ObjectContext; insomma, il MergeOption è associato indissolubilmente con la query compilata.
La soluzione è quella di duplicare la compilazione della query o meglio fare una compilazione separata per ogni valore della MergeOption che si intende usare. Purtroppo si ripeterebbe piu’ volte il codice della query LINQ. La soluzione ottimale è quella di usare un CompiledQueryReplicator che è una classe che permette di specificare la query LINQ una volta sola e automaticamente di compilare piu’ istanze della stessa. Le istanze vengono inserite in un Dictionary la cui Key è il tipo di MergeOption con cui si vuole compilare la query. L’idea è stata già esplicitata in questo progetto su CodePlex : http://dcutilities.codeplex.com e li si puo’ andare a recuperare le due classi CompiledQueryReplicator e EfCompiledQueryReplicatorFactory. Consiglio anche di leggere il tutorial per la spiegazione di come usarle. Di seguito riporto per semplicità il codice delle due classi.

    /// <summary>
    /// The CompiledQueryReplicator is a class that allows you to specify a LINQ query once, then
    /// automatically compile different instances of it. This is useful when you need multiple instances
    /// of the same query compiled with different <see cref="System.Data.Objects.MergeOption"/>s, 
    /// for example. Each instance is identified with a particular key of type <typeparamref name="TKey"/>.
    /// </summary>
    /// <remarks>
    /// <para>
    /// If you're using the Entity Framework (LINQ to Entities), it is suggested that you use the 
    /// <see cref="EfCompiledQueryReplicatorFactory{TKey}"/> class to instantiate instances of this
    /// class, as it makes the syntax shorter and automatically provides you with the Entity Framework
    /// compiled query compiler.
    /// </para>
    /// <para>
    /// This class is thread-safe.
    /// </para>
    /// </remarks>
    /// <typeparam name="TQuery">The type of the query</typeparam>
    /// <typeparam name="TKey">The type to use as the key</typeparam>
    public class CompiledQueryReplicator<TQuery, TKey>
    {
        private readonly Expression<TQuery> _QueryExpressionTree;
        private readonly Func<Expression<TQuery>, TQuery> _Compiler;
        private readonly IDictionary<TKey, TQuery> _CompiledQueries;
        /// <summary>
        /// Creates a CompiledQueryReplicator using the specified query that will be compiled with
        /// the specified compiler.
        /// </summary>
        /// <param name="query">The query's expression tree</param>
        /// <param name="compiler">
        /// A delegate that can compile the query expression tree into an actual query
        /// </param>
        public CompiledQueryReplicator(Expression<TQuery> query, Func<Expression<TQuery>, TQuery> compiler)
        {
            _QueryExpressionTree = query;
            _Compiler = compiler;
            _CompiledQueries = new Dictionary<TKey, TQuery>();
        }
        /// <summary>
        /// Returns the compiled query instance associated with the specified key. If
        /// no query instance has been created for the specified key, one will be
        /// and it will be returned.
        /// </summary>
        /// <param name="key">The key</param>
        /// <returns>The compiled query.</returns>
        public TQuery this[TKey key]
        {
            get
            {
                TQuery query;
                lock (_CompiledQueries)
                {
                    if (_CompiledQueries.ContainsKey(key) == false)
                    {
                        query = _Compiler(_QueryExpressionTree);
                        _CompiledQueries.Add(key, query);
                    }
                    else
                        query = _CompiledQueries[key];
                }
                return query;
            }
        }
    }
    /// <summary>
    /// Factory class that makes it easier to create <see cref="CompiledQueryReplicator{TQuery,TKey}"/>
    /// instances that hold LINQ to Entities compiled queries.
    /// </summary>
    /// <typeparam name="TKey">T
    /// he type to use as the key for the CompiledQueryReplicators created
    /// </typeparam>
    public static class EfCompiledQueryReplicatorFactory<TKey>
    {
        /// <summary>
        /// Creates a <see cref="CompiledQueryReplicator{TQuery,TKey}"/> that compiles LINQ to Entities
        /// queries.
        /// </summary>
        /// <typeparam name="TArg0">
        /// The <see cref="ObjectContext"/> that encapsulates the model connection and metadata.
        /// </typeparam>
        /// <typeparam name="TResult">
        /// The type of the query results returned by executing the delegate returned by the Compile method.
        /// </typeparam>
        /// <param name="query">The LINQ to Entities query expression to compile</param>
        /// <returns>The <see cref="CompiledQueryReplicator{TQuery,TKey}"/> created</returns>
        public static CompiledQueryReplicator<Func<TArg0, TResult>, TKey> Create<TArg0, TResult>(Expression<Func<TArg0, TResult>> query)
            where TArg0 : ObjectContext
        {
            return new CompiledQueryReplicator<Func<TArg0, TResult>, TKey>(query, CompiledQuery.Compile);
        }
        /// <summary>
        /// Creates a <see cref="CompiledQueryReplicator{TQuery,TKey}"/> that compiles LINQ to Entities
        /// queries.
        /// </summary>
        /// <typeparam name="TArg0">
        /// The <see cref="ObjectContext"/> that encapsulates the model connection and metadata.
        /// </typeparam>
        /// <typeparam name="TArg1">
        /// Represents the type of the parameter that has to be passed in when executing the delegate returned
        /// by the Compile method.
        /// </typeparam>
        /// <typeparam name="TResult">
        /// The type of the query results returned by executing the delegate returned by the Compile method.
        /// </typeparam>
        /// <param name="query">The LINQ to Entities query expression to compile</param>
        /// <returns>The <see cref="CompiledQueryReplicator{TQuery,TKey}"/> created</returns>
        public static CompiledQueryReplicator<Func<TArg0, TArg1, TResult>, TKey> Create<TArg0, TArg1, TResult>(Expression<Func<TArg0, TArg1, TResult>> query)
            where TArg0 : ObjectContext
        {
            return new CompiledQueryReplicator<Func<TArg0, TArg1, TResult>, TKey>(query, CompiledQuery.Compile);
        }
        /// <summary>
        /// Creates a <see cref="CompiledQueryReplicator{TQuery,TKey}"/> that compiles LINQ to Entities
        /// queries.
        /// </summary>
        /// <typeparam name="TArg0">
        /// The <see cref="ObjectContext"/> that encapsulates the model connection and metadata.
        /// </typeparam>
        /// <typeparam name="TArg1">
        /// Represents the type of the parameter that has to be passed in when executing the delegate returned
        /// by the Compile method.
        /// </typeparam>
        /// <typeparam name="TArg2">
        /// Represents the type of the parameter that has to be passed in when executing the delegate returned
        /// by the Compile method.
        /// </typeparam>
        /// <typeparam name="TResult">
        /// The type of the query results returned by executing the delegate returned by the Compile method.
        /// </typeparam>
        /// <param name="query">The LINQ to Entities query expression to compile</param>
        /// <returns>The <see cref="CompiledQueryReplicator{TQuery,TKey}"/> created</returns>
        public static CompiledQueryReplicator<Func<TArg0, TArg1, TArg2, TResult>, TKey> Create<TArg0, TArg1, TArg2, TResult>(Expression<Func<TArg0, TArg1, TArg2, TResult>> query)
            where TArg0 : ObjectContext
        {
            return new CompiledQueryReplicator<Func<TArg0, TArg1, TArg2, TResult>, TKey>(query, CompiledQuery.Compile);
        }
        /// <summary>
        /// Creates a <see cref="CompiledQueryReplicator{TQuery,TKey}"/> that compiles LINQ to Entities
        /// queries.
        /// </summary>
        /// <typeparam name="TArg0">
        /// The <see cref="ObjectContext"/> that encapsulates the model connection and metadata.
        /// </typeparam>
        /// <typeparam name="TArg1">
        /// Represents the type of the parameter that has to be passed in when executing the delegate returned
        /// by the Compile method.
        /// </typeparam>
        /// <typeparam name="TArg2">
        /// Represents the type of the parameter that has to be passed in when executing the delegate returned
        /// by the Compile method.
        /// </typeparam>
        /// <typeparam name="TArg3">
        /// Represents the type of the parameter that has to be passed in when executing the delegate returned
        /// by the Compile method.
        /// </typeparam>
        /// <typeparam name="TResult">
        /// The type of the query results returned by executing the delegate returned by the Compile method.
        /// </typeparam>
        /// <param name="query">The LINQ to Entities query expression to compile</param>
        /// <returns>The <see cref="CompiledQueryReplicator{TQuery,TKey}"/> created</returns>
        public static CompiledQueryReplicator<Func<TArg0, TArg1, TArg2, TArg3, TResult>, TKey> Create<TArg0, TArg1, TArg2, TArg3, TResult>(Expression<Func<TArg0, TArg1, TArg2, TArg3, TResult>> query)
            where TArg0 : ObjectContext
        {
            return new CompiledQueryReplicator<Func<TArg0, TArg1, TArg2, TArg3, TResult>, TKey>(query, CompiledQuery.Compile);
        }
    }

 

Il codice di esempio riscritto con queste classi diventa :

 

public class QueryCompiled 
{
  public static readonly CompiledQueryReplicator<Func<MyEntities, string, Users>, MergeOption> 
             GetUserByEmail = EfCompiledQueryReplicatorFactory<MergeOption>.Create( 
                                     (MyEntities ctx, string email) => 
                                     (from a in ctx.Users 
                                     where a.Email == email 
                                     select a).FirstOrDefault());
}
public class A
{
  public string GetUserName(string email)
  {
    using (MyEntities context = new MyEntities()) 
    {
      context.Users.MergeOption = MergeOption.NoTracking; 
      var users= (QueryCompiled.GetUserByEmail[MergeOption.NoTracking](context, email));
      return users.Name;
    }
  }
  public void SetUserName(string email, string name)
  {
    using (MyEntities context = new MyEntities()) 
    {
      var users= (QueryCompiled.GetUserByEmail[MergeOption.AppendOnly](context, email)); 
      users.Name = name;
      context.SaveChanges();
    }
  }
}

Da notare che nell’invocazione della query si specifica il tipo di MergeOption che si intende usare. Se esiste una query compilata con quell’opzione nel dizionario viene ritornata altrimenti ne viene creata una.

author: Moreno Borsalino | posted @ domenica 17 gennaio 2010 20.49 | Feedback (0)

Real Code Day 4.0 … un evento perfetto.


Leggo solo ora dal blog di AspItalia questo post : Online (quasi tutti) i video di Real Code Day 4. Era un evento organizzato ai primi di Dicembre a Firenze. Era uno di quegli eventi che avrei voluto seguire ma che la distanza rendeva impossibile. La disponibilità delle registrazioni video è una piacevole sorpresa; finalmente posso andare a vedere ed ascoltare cosa è stato presentato. Complimenti agli organizzatori per l’idea ! Leggo poi che l’evento era pure trasmesso online in streaming (Real Code Day 4.0 anche in streaming!). Ancora complimenti !
E dal post di ringraziamento (Real Code Day 4.0: grazie, demo e Azure) leggo che “ci sono stati dei picchi di connessioni molto ma molto interessanti”. Allora c’è interesse a seguire gli eventi a distanza ! 
Streaming online e registrazioni video sono due elementi che reputo fondamentali per dire che questo è un evento perfetto. Dovrebbe essere di modello a tutti gli eventi. Purtroppo dopo l’abbandono di Microsoft alla moda dei webcast online si è preferito puntare alla moda delle community locali che hanno, secondo il mio parere, lo svantaggio di diluire sul territorio le conoscenze e renderle difficilmente fruibili. Almeno per me non è per nulla pratico andare personalmente agli eventi organizzati nelle varie città italiane. Diventa una sorta di giro d’Italia dello sviluppatore. Lo so che per molti è piu’ importante incontrare gli amici o la cena sociale con annessa gara a chi mangia la bistecca più grande. A me interessano puramente i contenuti. Purtroppo gli eventi organizzati non vengono mai registrati o se viene fatto le registrazioni sono mantenute segrete. Si vedono solo gli annunci con bei titoli sugli argomenti, spesso molto interessanti, si vedono poi le foto fatte delle facce soddisfatte del pubblico. Qualcuno rende disponibili le slide. Ma il risultato finale è che solo pochi fortunati sapranno cosa è stato proferito. Mi ricordano molto le società segrete carbonare o le logge massoniche o le sette religiose.

Questo Real Code Day invece è stato fatto con lo spirito della massima divulgazione. Ancora bravi ! La speranza è che anche gli altri eventi vengano fatti secondo questo “pattern”. Se l’esperienza dell’online ha dato picchi molto interessanti vuol dire che c’è un popolo che apprezzerebbe una maggiore diffusione. Scusate lo sfogo ma è una cosa che ho in testa da tanto tempo. Spero non sia una fissa tutta e solo mia.

author: Moreno Borsalino | posted @ domenica 17 gennaio 2010 18.13 | Feedback (5)

[TFS] Togliere i log del database per guadagnare spazio


Ieri mentre facevo l’ultimo Checkin della giornata ottengo l’errore TF30042: The database is full. Momento di panico.
Oggi con calma trovo la soluzione. Il problema è causato dalla crescita abnorme dei file di log del database con conseguente rienpimento del disco. Il TFS server gira su una VM e quindi non ha molto spazio di disco. Avrei potuto aumentare la dimensione della VM ma cercando in giro ho trovato una soluzione che mi sembra piu’ adatta alla mia configurazione : TF30042: The database is full. Contact your Team Foundation Server administrator.
In sostanza viene consigliato di usare i database di TFS in Simple Recovery mode, ossia senza file di log. Nel mio caso cio’ non è grave poichè sul database di TFS ho aggiunto un job per fare il backup di tutti i database ogni notte.

author: Moreno Borsalino | posted @ sabato 16 gennaio 2010 18.42 | Feedback (0)

[OT] Lettera a Babbo Natale


Natale, tempo di viaggi, di riflessioni, di pensieri e desideri. Quest’anno ho voluto provare l’uso di un netbook in viaggio. Piu’ che i risultati mi hanno sorpreso le riflessioni. Ma andiamo con ordine. Ho avuto per le mani un Asus eeepc 901, si trtta di un modello vecchio ma per ora il nuovo non è per niente diverso. E’ un pc con Atom N270, schermo da 10 pollici, disco SSD da 16 GB, rete wifi e 3G integrata. Niente Bluetooth e sistema operativo Windows XP. Non si può certo definire un pc da lavoro ma piuttosto un pc con cui svolgere ogni genere di attività in condizioni “ristrette”. Direi che si puo’ fare lettura e scrittura di documenti, vedere video e ascoltare musica, si possono fare anche giochi che non richiedano grafica troppo spinta. Ho provato anche a lavorare con Visual Studio; si soffre un po’ lo schermo piccolo ma tutto funziona alla perfezione. Anche la connessione 3G con il server TFS regge bene. La parte 3G permette connessioni mobili fino a HSUPA. Soltanto con l’aggiornamento del firmware del chip EM770 si riesce ad ottenere delle connessioni stabili e veloci. La batteria a 6 celle fornisce una buona autonomia ed il formato piccolo permette un’ottima maneggevolezza.
Tutto sembra perfetto e fantastico pero’ appena mi fermo a riflettere mi sorgono un sacco di dubbi e desideri.
La prima cosa che vorrei è poter fare e ricevere telefonate; se c’e’ un modulo per la connessione 3G che permette di ricevere e inviare sms perchè non posso fare e ricevere telefonate ? I cellulari lo fanno perchè non puo’ un netbook ? Forse il chip em770 non supporta le chiamate in voce ? Capperi, gli ingegneri della Huawei sono stati cosi’ miopi da non mettere questa piccola funzionalità nel chip ? Possibile che nessuno l’abbia chiesta ? Eppure per usare il 3G devo togliere la Sim dal cellulare e metterla nel netbook restando di fatto senza telefono. A me sembra lampante spostare la comunicazione telefonica sul netbook. In tal modo potei anche buttare il cellulare, infatti avrei un super cellulare con batterie a lunga durata con cui potrei collegarmi con una cuffia via cavo oppure Bluetooth. Anzi se vado oltre potrei immaginare le funzioni del cellulare gestite via SideShow mentre il netbook è spento. In tal modo “qualcuno” potrebbe rivitalizzare una tecnologia praticamente morta e dimenticata.
Immaginiamo poi che il netbook abbia uno schermo multitouch; allora posso immaginare tante belle applicazioni stile iphone ma fatte per un pc. A questo punto chi vorrebbe ancora un iphone ? Io sicuramente no, avrei un mega Iphone con schermo da 10 pollici e CPU da oltre un 1 GHz. Poi se i progettisti fossero un pelo furbi oltre al multitouch farebbero lo schermo adatto anche ad essere usato come tablet pc con una penna apposita. Facciamo ovviamente lo schermo ruotabile per ottenere una superficie da megacellulare. L’oggetto che si ottiene farebbe mangiare la polvere anche ai vari Kindle ed affini. Inoltre se è vera la notizia che Apple intende lanciare un tablet pc allora “qualcuno” dovrebbe preoccuparsi seriamente poichè se Apple lo fa potrebbe togliere l’esclusiva ed il mercato ai TabletPc Microsoft.
Ma non è finita. Se vogliamo far diventare il netbook un super cellulare allora bisogna aggiungere ancora un GPS integrato; immaginate Tom Tom come si vedrebbe bene ma soprattutto cosa altro potrebbero aggiungere sullo schermo in termini di informazioni: nuvole, velocità del vento, frecce luminose che indicano McDonalds oppure amici online sul Messenger che passano da quelle parti e facendo click col dito sullo schermo posso fare una telefonata per un saluto ed un incontro veloce.
Ma il GPS non mi basta, voglio anche il sensore accelerometrico che mi aggiusta lo schermo da verticale a orizzontale quando ruoto il netbook oppure che posso usare nei giochi che lo sfruttano e che vorrei vedere abbondanti su Games for Windows Live.
Di più ! Il netbook ha uno schermo decente per vedere i video e quindi anche la televisione. Ebbene voglio un ricevitore DVB-T integrato ma non voglio il Media Center nel sistema operativo; è troppo pesante e complesso. Basta avere un programma per ricevere la TV, vederla ed al limite registrare il programma. Anche usando il netbook in casa agganciato alla wifi domestica potrei sempre vedere musica e video condividendo le cartelle remote sul server o sul NAS casalingo.
Il netbook ben riempito di musica farebbe dimenticare Ipod e Zune. Poi se l’ascolto avvenisse tramite SideShow a computer spento sarebbe veramente il massimo.  
Vorrei anche avere una webcam integrata da 10 milioni di pixel o anche di piu’ per poter fare non solo foto in HD ma per poter registrare anche video in qualità HD 1080p. Un bel disco da 500GB completerebbe il tutto. Ovviamente non SSD poichè in questo momento renderebbe il netbook più costoso di un gioiello ma un disco normale non dovrebbe essere un problema inserirlo nel case. In alternativa la webcam potrebbe sempre scrivere su una scheda SD ormai di capacità di 32 GB e presto da 64GB.
Infine una piccola batteria al plutonio della durata di 20 anni potrebbe completare perfettamente il tutto ma … non si puo’ avere tutto :-)

Ebbene se “qualcuno” facesse un netbook con tutto questo penso che potrei buttare via tranquillamente tutti i cellulari di ogni tipo, windows mobile ed iphone che siano. Inoltre visto che orma il mercato dei cellulari è dominato, senza speranza di cambiamenti, da Iphone e che il futuro Windows Mobile 7 se mai uscirà non potrà cambiare di molto la realtà del mercato allora l’uscita di un nuovo oggetto misto cellulare netbook aprirebbe nuovi spazi di mercati e possibilità a “qualcuno” in difficoltà a vendere vecchie idee. E visto che si tratta di un PC dovrebbe avere il massimo supporto dalla parte buona dell’azienda che gode dei successi del settore PC. Qualcuno potrebbe contestare che un tale oggetto assomiglia molto all’UMPC; effettivamente molte delle caratteristiche sono simili ma l’UMPC è un altro di quegli UFO mai visti veramente sugli altari del successo. Ovviamente un tale oggetto non potrebbe essere fatto solo da “qualcuno” ma ci vorrebbe il coinvolgimento di altri costruttori di un certo peso che già fanno dei notebook e dei cellulari; basta metter insieme le due cose a livello ingegneristico: tutta elettronica che esiste. Si otterrebbe un oggettino che sarebbe l’anello di congiunzione tra mondo cellulare, PC e diciamo …anfibio.
Quindi caro Babbo o nababbo Natale potresti farmi trovare sotto l’albero, a questo punto direi pasquale, questo “netbook” dei sogni ? A me piacerebbe un sacco. E sono pronto a scommettere che piacerebbe ad un sacco di altra gente

author: Moreno Borsalino | posted @ martedì 29 dicembre 2009 20.22 | Feedback (6)

Parallel Extension per .Net 3.5 (Px)


La programmazione parallela nel framework 3.5 era possibile fino a un po’ di tempo fa con una CTP apposita. Poi si disse che le estensioni parallele erano disponibili solo su .Net 4. Invece si posso ritrovare le stesse estensioni anche in 3.5. Infatti le ho ritrovate dentro Rx: Reactive Extensions to .NET. Rx è una libreria per la creazione di programmi asincroni e basati su eventi utilizzando delle observable collection. Rx l’ho scoperto guardando le sessioni del PDC. Sono rimasto impressionato dalla potenza espressiva dei costrutti messi a disposizione. Ma dentro Rx è stato inserito Px esattamente come è disponibile in .Net 4.

Basta inserire nel programma un riferimento alla dll System.Threading.dll ovviamente dopo aver installato Rx. Questo è un passo che non si deve fare in .Net 4 poichè è già presente nei componenti del CLR. Ci possono essere differenze nelle prestazioni a favore di .Net 4 poichè quest’ultimo si avvantaggia delle migliorie apportate al ThreadPool

Altra risorsa per Px è il blog Parallel Programming with .NET
Mentre chi fosse interessato a delle best practices per sviluppare usando dei pattern paralleli c’è il documento Patterns for Parallel Programming

author: Moreno Borsalino | posted @ martedì 24 novembre 2009 21.35 | Feedback (4)

Microsoft al PDC regala questo portatile


Al recente PDC Microsoft ha regalato ai partecipanti un portatile che serve a dimostrare tutte le bellezze di Windows 7. Si tratta di un modello derivato dall’Acer Aspire 1420P di serie a cui sono state apportate alcune migliorie e su cui è stato installata una suite di SW molto corposo.
Intanto diciamo dove si trova la user guide ufficiale : Acer Aspire 1420P Convertible Tablet PC

Se è stato scelto da Microsoft evidentemente deve essere la “cosa” che al momento sul mercato serve ad esprimere meglio le potenzialità di Windows 7 e quindi vale la pena analizzarlo. Le caratteristiche tecniche sono :

Una CPU Intel Celeron U2300 dual core a 1.2GHz, non molto performante purtroppo, nel Windows Experience Index la CPU ha un punteggio di 3,9
2GB of DDR3 1066MHz RAM upgradabile ad 8GB),
250GB HD,
un monitor da 11.6” multitouch (2 soli punti) usabile anche come tablet,
un sensore  accelerometrico che orienta automaticamente il desktop quando si gira il computer da orizzontale a verticale

Qualche altra immagine la si puo’ trovare qui

Purtroppo come dicevo non è in commercio ma spero che i costruttori prendano esempio e offrano presto qualcosa di simile o migliore … dopotutto Natale è vicino smile_wink

author: Moreno Borsalino | posted @ sabato 21 novembre 2009 18.56 | Feedback (0)

L’antivirus free di Microsoft e’ buono?


Ne avevo gia’ parlato un anno fa (Antivirus gratis da Microsoft ?) ma ora e’ uscito ufficialmente e la prima domanda che viene in testa e’: ma quanto e’ valido rispetto agli altri ?
Nell’articolo Which is the Best Free AntiVirus? AntiVir Versus Microsoft Security Essentials - Part 2 viene fatto un confronto con un’altro antivirus free molto famoso (che uso personalmente con gradimento). Ebbene il risultato sul confronto del riconoscimento dei virus pende a favore di Avira. Per cui per ora non cambio.

author: Moreno Borsalino | posted @ giovedì 1 ottobre 2009 12.08 | Feedback (17)

Upgrade a Windows 7 con problemi


Avendo letto e sentito meraviglie di Windows 7 mi sono deciso a fare l’upgrade di uno dei computer da Vista a Win7. Premetto che avevo provato in passato le versioni beta e rc su macchine virtuali e non avevo avuto problemi ma erano semplici prove niente di serio. Per l’upgrade di un computer da lavoro invece ho deciso di non fare le cose avventate; ho aspettato la versione finale, ho lanciato prima Windows Upgrade Advisor e fissato tutti i problemi. Ho disinstallato tutti i programmi non necessari o quelli che mi puzzavano di probabili fonti di problemi (per esempio il windows mobile device, quicktime, divx, ecc).
Alla fine il PC parte con Windows 7. Apparentemento tutto sembra a posto ma …
la cosa piu’ devastante e’ il menu “Start Menu” completamente vuoto. Ricerca su Google e scopro che in realta’ sono in tanti ad aver avuto lo stesso problema. Pero’ le soluzioni che propongono non funzionano.
L’antivirus Bitdefender aveva passato l’upgrade advisor ma ora quando parte mi segnala che il firewall TDI filter Driver ha un problema e resta bloccato. Il tasto della soluzione non porta a nulla.
Addirittura Windows 7 mi dice che ci sono due antivirus: Symantec e bitdefender. Il bello e’ che il primo l’ho disinstallato un bel po’ di tempo fa.
Il device manager mi riporta diversi pallini gialli, eppure anche li l’upgrade advisor non aveva segnalato problemi. Addirittura e’ spuntato un device sconosciuto, ma ogni cosa nel pc sembra funzionare per cui mi domando cosa sia.
Faccio un windows update: mi viene chiesto di installare la SP1 per Visual Studio 2005. Era gia’ installata prima pero’ se me lo chiede vuol dire che gli serve. Procedo …
C’e’ anche il media center. La scheda TV sembra averla riconosciuta ed il windows update ha aggiornato il driver per cui passo alla configurazione della TV del Media Center. Installazione Play Ready a posto, scaricamento guida TV a posto, scan dei canali partito e …. bam! schermata blu.

Morale: una delle tante dicerie recitava che i sistemi operativi Microsoft andrebbero usati solo dopo la prima service pack. Vuoi vedere che aveva ragione ? Oppure si tratta solo di sfiga ?

author: Moreno Borsalino | posted @ martedì 1 settembre 2009 15.51 | Feedback (3)

SQL BPA command line has stopped working


E’ l’errore che ottenevo tutte le volte che tentavo di installare la SP3 di SQL 2005 Express with advanced Services su un PC con Vista. E poi desistevo in quanto non sapevo cosa fare.
Finalmente ci sono riuscito semplicemente copiando il file BPAClient.dll che si trova in C:\Program Files (x86)\Microsoft SQL Server\90\Setup Bootstrap\BPA\bin nella directory C:\Program Files (x86)\Microsoft SQL Server\90\Setup Bootstrap\BPA. Poi si ripete l’installazione della SP3 questa volta con successo.

author: Moreno Borsalino | posted @ domenica 30 agosto 2009 18.37 | Feedback (2)

Il PC più scarso per Windows 7


Si dice che Windows 7 sia molto più leggero e performante di Vista e quindi può girare su PC vecchi. Ma quanto vecchi ?

Dall’articolo Windows 7, A New Low si scopre che il record è quello di "Hackerman1" che è riuscito a far girare Win7 su un PC con Pentium II a 266 MHz, 96MB di memoria e 4MB di scheda grafica. Ha provato anche con 64 MB di RAM ma ha ottenuto l’errore di memoria insufficiente.

author: Moreno Borsalino | posted @ domenica 16 agosto 2009 21.12 | Feedback (0)