Mi sono spesso trovato di fronte al conflitto tra la programmazione Object Oriented e la necessità di usare le caratteristiche multithreading del sistema operativo. Alla fine si tratta di scrivere una procedura, sotto forma di metodo, e pur esistendo delle classi che lo fanno, in se la cosa non si presta bene ad essere racchiusa in un'ottica object oriented. Qui sotto vi propongo una classe che usa il pattern Singleton per incapsulare un thread e tutto ciò che serve per controllarlo.

Io l'ho realizzata per racchiudere i vari thread che lavorano all'interno di un Windows Service che ho creato, e l'ho trovata molto comoda.

using System;
using System.Threading; 

public class WorkingThread
 {
    private static WorkingThread m_Instance;
    private AutoResetEvent m_ExitEvent;
    private Thread m_Thread;
    private bool m_Running;

    private WorkingThread()
    {
        m_ExitEvent = new AutoResetEvent( false );
        m_Running = false;
    }

    public static WorkingThread Instance
    {
        get
        {
            if ( m_Instance == null )
                m_Instance = new WorkingThread();

            return m_Instance;
        }
    }

    public bool IsRunning
    {
        get { return m_Running; }
    }

    public void Start()
    {
        if ( !IsRunning )
        {
            m_ExitEvent.Reset();

            ThreadStart startInfo = new ThreadStart( Thread_Proc );
            m_Thread = new Thread( startInfo );
            m_Thread.Start();

            m_Running = true;
        }
        else
            throw new InvalidOperationException( "Thread already running" );
    }

    public void Stop()
    {
        if ( IsRunning )
        {
            m_ExitEvent.Set();
            m_Running = false;
        }
       
else
            throw new
InvalidOperationException( "Thread already stopped" );
    }

    protected void Thread_Proc()
    {
        WaitHandle [] handles = new WaitHandle [] { m_ExitEvent };

        while( WaitHandle.WaitAny( handles, 1000, false ) == WaitHandle.WaitTimeout )
        {
       
     // do something
            Thread.Sleep( 1000 );
        }
    }
}

L'uso è banale. La classe ha una proprietà Instance che rappresenta il thread che deve essere lanciato e ha i metodi Start() e Stop() per avviarlo e fermarlo.

public void Main()
{
    WorkerThread.Instance.Start();
    //
    WorkerThread.Instance.Stop();
}

Ancora una volta l'applicazione dei design pattern dimostra la sua potenza.

N.B. Approfondite i commenti a questo post, perchè c'è molto da imparare.


Ultimo giorno di corso, per fortuna. Ed oggi, un simpatico evento ha allietato l'inizio della mia giornata.

Ambientazione: Interno giorno. Un'aula anonima nei sotterranei di un grande ente statale, nel quale non si dice "Buon giorno", ma "Buon Java"

Al termine di una trance di lezione c'è da fare un esercizio. E' necessario scrivere un breve pezzetto di HTML, diciamo una ventina di righe, ed io bello come il sole inizio; vado sul desktop e dritto come un fuso, apro Visual Studio .NET, creo il file e comincio a scrivere. Tempo 20 secondi netti, il file è pronto senonchè passa l'insegnante e si accorge di VS.

Nemmeno fossimo in uno spettacolo di rivista in men che non si dica mi ritrovo al centro dell'ilarità generale... Yeah, guarda questo, "Microsoft Dipendente", Visual Studio... Questi i termini nei quali sono stato apostrofato. Intanto il mio bel file è pronto e tutti gli altri arrancano a scrivere tag Html e Xml all'interno del non censurabile notepad.

Ammesso e non concesso che usare Visual Studio per venti righe di HTML sia eccessivo, mi chiedo quanta parte dell'ilarità generale sia dovuta all'invidia e quanta altra alla discriminazione.

A voi la risposta...

tags: - categories:

Mi è stato appena confermato che sul numero di Novembre di Computer Programming (#140) uscirà un articolo a mia firma che porta lo stesso titolo di questo post. L'articolo che fa parte dello speciale linguaggi, fornisce una panoramica abbastanza approfondita delle nuove feature del compilatore C# nel Framework 2.0. Spero sia un buon punto di partenza per iniziare a prendere confidenza con il linguaggio, con il più il vantaggio di essere scritto in italiano.

Non mancherò di postare un avviso il giorno stesso in cui uscirà la rivista, giusto per rinfrescarvi la memoria.

Buona lettura. 


Penultimo giorno di corso.

Ho appena terminato l'ennesimo inutile "esercizio", per la serie clicca questo, scrivi quello, clicca Ok et voilà tutto funziona... ma cosa è rimasto? Assolutamente nulla. Sono certo che uscito da queste quattro mura, mi ritroverò nuovamente nella necessità di studiarmi da solo tutto il prodotto, con in più un tarlo che rode: "ma se la funzionava, cosa faccio di sbagliato adesso"?

Certi "corsi" bisognerebbe vietarli per legge. E adesso chi lo spiega al mio capo, che dopo 6 giorni di questa solfa, l'unico vantaggio è l'avere la certezza che può funzionare, se sai come fare, ma... saperlo fare è un'altra cosa!!!

tags: - categories:

Come promesso, in un mio precedente post, sono finalmente a spiegare i motivi per cui personalmente ho eletto C# a mio linguaggio di riferimento. Badate, questo non significa che io mi rifiuti di sviluppare in altri linguaggi, ma semplicemente che potendo scegliere, a ragion veduta abbraccio C#.

Il primo motivo è di carattere puramente affettivo. Le mie prime esperienze di programmazione seria le ho fatte in Ansi "C", e poi in C++ e C# ha il pregio di ricordarmelo. Certo, non è la stessa cosa in fatto di sintesi ma talvolta mi piace scrivere la chiamata ad un metodo, e il test del risultato sulla stessa riga come era abitudine indimenticata del buon vecchio C.

Il secondo motivo è di carattere più politico. Non sopporto l'arroganza, e tantomeno i moralisti. Perciò Java non fa per me. Già tempo fa ho avuto l'occasione di scrivere sul mio rapporto con certi programmatori Java, e trovo che sia ampiamente corretto quello che ha detto Lorenzo in risposta ad un mio post: E' troppo facile per il coniglio considerarsi vincitore quando gareggia con la tartaruga, ma pensare di poter considerare questa facile vittoria motivo di orgoglio e nobiltà è davvero troppo. Ho la pretesa di voler scrivere buon codice e ritengo di poterlo fare almeno tanto bene in C# quanto in Java. Se non di più. Inoltre considero C# anticonformista. E questo per me è addirittura una bandiera da portare. Anticonformista, nel senso che non si conforma alle morali dettate dai benpensanti. In che senso? Per quale motivo devo essere obbligato a fare try e catch di tutto quello che si muove? Questo è un conformismo. Voglio sentirmi libero di decidere io come, dove e quando trappare. Punto.

Terzo. In questi giorni ho scritto un articolo, che se tutto va bene uscirà a novembre, che mi ha dato l'occasione di approfondire alcuni dettagli implementativi dei compilatori C#2.0 e Java 1.5 (o 5.0 che dir si voglia). Il risultato di questo paragone mi ha fatto comprendere meglio perchè C# è meglio di Java, e non mi riferisco a feature del framework, ma solo esclusivamente al compilatore. Avrete già letto, quello che accadrà ai generics in ambito Java, e se ho ben chiaro cosa ha mosso i progettisti di C#, non ho altrettanto chiaro le finalità di quelli Java.

Quarto ed ultimo. Il mito della portabilità. Mi è sempre andato stretto, il dovermi confrontare con questa caratteristica che confesso mi lascia spesso interdetto. Ma più e più volte mi sono chiesto: ma vale veramente la pena costringere il mio cliente a spendere il 10-20% in più sull'hardware per poter far girare una applicazione talmente generica da poter funzionare ugualmente su Windows che su Linux o Mac? La risposta a questa domanda non la so. Ma certamente se metto assieme il risparmio in termini di risorse macchina, e la maggiore produttività del linguaggio, la bilancia per me pende di certo su C#.

Questi sono i miei perchè.

Buonanotte.


Ho qualcosa da aggiungere rispetto al post di Lorenzo Barbieri sui Custom CSS Selectors. Se notate la tendina denominata "Display Skin" contiene una serie di Skin con il nome composto. Se tentate di aggiungere nuovi stili o di sovrascrivere quelli preesistenti su queste skin, non ottenete alcun risultato apprezzabile. Questo perchè .TEXT usa due css; se prendiamo la skin del mio blog marvin3-red, i css sono:

/skins/marvin3/style.css
e
/skins/marvin3/red.css

gli stili inseriti in Custom CSS Selectors vengono caricati al posto del secondo css solo quando selezionate una skin semplice (e non tutte)

Perciò, se come me vi siete innamorati di uno "stile composto", ma volete apportare delle modifiche dovete procedere così:

1) selezionate lo skin che preferite
2) scaricate lo skin secondario che trovate nell'html
3) impostate il relativo skin base
4) copiate il contenuto del file secondario nei Custom CSS Selectors

A questo punto potete apportare le modifiche che volete mantenendo come base la vostra skin prediletta...

fiuuuu...

tags: - categories:

Continuando a leggere l'articolo di cui ho parlato nel mio ultimo post, ho scoperto una cosa inquietante: Il compilato generato da Java 1.5 "Tiger", sarà perfettamente eseguibile su una virtual machine precedente a questo compilatore.

Questo si traduce nel seguente ragionamento rispetto i Generics: Nessuna modifica è stata introdotta nel bytecode di Java, quindi i generics sono una mera traduzione del codice Java 1.5 in Java 1.4 oggetto della compilazione finale. Questo significa che per effettuare una traduzione vengono introdotti un'infinità di cast e dei metodi bridge per consentire le conversioni. (leggete l'articolo, è tutto nero su bianco)

Ora, se mettiamo assieme le problematiche di boxing/unboxing di cui sopra e le attività di cast a go-go, ne otteniamo che le performance di un codice che usa i generics saranno notevolmente peggiorate.

Conclusione: I generics in Java sono una pura operazione di marketing.

Chissà perchè?


Mentre facevo una piccola ricerca di materiale per un mio prossimo articolo, mi sono imbattuto nel seguente paragrafo che spiega molto bene le differenze di implementazione dei Generics in Java e C#. Esso è tratto da Java Generics - Introduction - Angelika Langer

Translation of Generics

A compiler that must translate a parameterized type or method (in any language) has in principle two choices:

  • Code specialization . The compiler generates a new representation for every instantiation of a parameterized type or method. For instance, the compiler would generate code for a list of integers and additional, different code for a list of strings.
  • Code sharing . The compiler generates code for only one representation of a parameterized type or method and maps all the concrete instantiations of the generic type or method to the one unique representation, performing type checks and type conversions where needed.

Code specialization is the approach that C++ takes for its templates. The C++ compiler generates executable code for every instantiation of a template. The downside of code specialization of generic types is its potential for code bloat.  A list of integers and a list of strings would be represented in the executable code as two implementations of two different types.

This is particularly wasteful in cases where the elements in a collection are references (or pointers), because all references (or pointers) are of the same size and internally have the same representation. There is no need for generation of mostly identical code for a list of references to integers and a list of references to strings.  Both lists could internally be represented by a list of references to any type of object. The compiler just has to add a couple of casts whenever these references are passed in and out of the generic type or method. Since in Java most types are reference types, it deems natural that Java chooses code sharing as its technique for translation of generic types and methods.  [C#, by the way, uses both translation techniques for its generic types: code specialization for the value types and code sharing for the reference types.]

One downside of code sharing is that it creates problems when primitive types are used  as parameters of generic types or methods. Values of primitive type are of different size and require that different code is generated for a list of int and a list of double for instance. It?s not feasible to map both lists onto a single list implementation. There are several solutions to this problem:

  • No primitive types . Primitive types are prohibited as type arguments of parameterized types or methods, that is, the compiler rejects instantiations such as a List .
  • Boxing . Primitive type values are boxed automatically so that internally references to the boxed primitive value were used. (Boxing is the process of wrapping a primitive value into its corresponding reference type, and unboxing is the reverse (see / BOX /.) Naturally, boxing has an negative effect on performance due to the extra box and unbox operations.

Java Generics uses the first approach and restricts instantiation of generics to reference types. Hence a LinkedList is illegal in Java. [In C++ and C# primitive types are allowed as type arguments because these languages use code specialization (in C++ for all instantiations and in C# at least for instantiations on primitive types).]

A me pare un altro punto a favore di C# (vedi boxing/unboxing), ma giudicate voi.