World Names Profiler
Se siete curiosi di conoscere la diffusione del vostro cognome nel mondo, visitate questo sito.
Vacanze
Finalmente domani inizieranno le mie vere vacanze estive (o quasi dato che siamo a settembre), staccando la spina da tutto prima dell'inizio del nuovo anno accademico e l'inizio dei nuovi progetti. Una pausa rigenerante. Alla prossima settimana.
Buon week-end a tutti
Ho notato solo oggi un comportamento "curioso" di SQL Server Management Studio 2008. Dovevo cambiare il tipo di dato di un campo in una tabella, quindi seleziono il Database, seleziono la tabella, vado in modalità "design", cambio il tipo di dato, salvo e...
Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes to a table that can't be re-created or enabled the option Prevent saving changes that require the table to be re-created.
In pratica in SQL Server 2008, qualsiasi operazione su una tabella che comporta una DROP e una CREATE della stessa, di default è inibita. Per riavere il comportamento "classico" di SQL Server 2005, basta andare in Tools / Options / Designers e togliere la spunta su Prevent saving changes that require table re-creation:
Le operazioni che comportano DROP+CREATE di una tabella sono:
- Aggiunta di nuove colonne nel mezzo della tabella.
- Eliminazione di una colonna.
- Cambio del tipo di dato di una colonna o della sua nullability.
- Cambio dell'ordine delle colonne nella tabella.
Riferimento: http://msdn.microsoft.com/en-us/library/bb895146.aspx
Cercando risorse su LINQ, sono capitato su questo post del mitico Scott Guthrie, in cui si parla di ASP .NET Dynamic Data, una feature che fa parte delle ASP .NET 3.5 Extensions e che consente di creare con grande facilità siti web per l'inserimento, la visualizzazione e la modifica dei dati contenuti in un database, utilizzando LINQ-to-SQL. Me lo segno, sperando di poterci dare un'occhiata al più presto.
Non ho parole.
Pensavo non fosse vero.
Invece Patrick Tisseghem ci ha lasciato.
Era un grande professionista ed un bravo divulgatore, sempre presente alle SharePoint Conference, doveva esserci anche quest'anno...
Ciao Patrick e grazie di tutto.
Ci sono dei motivetti che ascolti una volta e non ti escono più dalla testa: l’inno dei mondiali di ciclismo su strada che si terranno a Varese a fine Settembre è uno di quelli.
Un po’ sambeggiante, scritto da Alberto Testa e musicato da Memo Remigi, mette in evidenza le bellezze di Varese, la Città Giardino.
Il video mostra degli splendidi scorso del paesaggio che circonda Varese: videoclip dell’inno Varese VA!!
E se dopo averlo sentito proprio non potete fare a meno di riascoltarlo e lo volete perfino come suoneria del cellulare: suoneria Varese VA (MP3, AAC e WAV).
Io sarò in giro con la mia nuova bicicletta (sempre se arriva in tempo) domenica 28 in occasione della prova in linea elite, se qualcuno è da quella parti, faccia un fischio, magari ci si vede.
Visto che mio fratello blogga cose del genere :) io rispondo con la news del giorno: AutoCollage 2008.
Non l'ho ancora provato, ma qualche screen shot carino già si vede...chissà magari è all'altezza...;))
Questo post è nato all'improvviso, da un fulmine a ciel sereno che mi ha ricordato una cosa di cui si è parlato non molto tempo fa..
Qualcuno si ricorda dello scandalo evasione da parte delle società concessionarie delle "slot da bar"?
No?
Vi rinfresco io allora..
**98 MILIARDI DI TASSE EVASE**
(novantottomiliardidieuro).. dai monopolisti del gioco d'azzardo legalizzato in Italia.. tutti quei soldi sono pari alla metà del nostro debito pubblico.. una cifra sconcertante, specie se si và a pensare poi a chi è finito in tasca tutto quel denaro..
Ovviamente, come in ogni buon sistema che non funziona, tutto è stato infossato e nessuno più si è chiesto nulla..
Nel tutto, la Corte dei Conti ha chiesto alle suddette società di pagare decine di miliardi di euro per il risarcimento del danno subito dallo Stato, e al dottor Giorgio Tino, il direttore dell’ AAMS, il pagamento di 1,2 miliardi per risarcimento danni..
Ma alla fine dei giochi, non sapremo mai dove sono andati a finire i soldi.. preferisco non continuare coi discorsi, perché ci perderemmo dentro politica, mafia, amicizie tra famiglie potenti e quant'altra immondizia possiamo immaginare..
Ho fatto questo post solo per ricordare la più grande evasione della storia Italiana.. : ) ..festeggiamo molte cose inutili, credo che sia da festeggiare anche questa. Un po di tecnologia, un po di ingegno, tanto senso del furto.. bisogna prendere esempio dalla genialità di qualcuno.
Ovviamente l'ultima frase era in senso ironico.. concludo il post con un paio di link, ci hanno pure fatto una wiki su questa evasione... :D
http://it.wikinews.org/wiki/Italia:_i_Monopoli_di_Stato_hanno_evaso_98_miliardi_di_tasse
L'altro invece riguarda una petizione, sempre sull'evasione..
http://firmiamo.it/98miliardidieuroevasi
Stay tuned!
Nel caso succeda anche a voi... dopo l'installazione dell'SP1 di VS2008 non mi funzionava più la possibilità di aggiungere "items" alla barra degli strumenti. Nell'Event Viewer trovavo qualcosa del genere:
.NET Runtime version 2.0.50727.3053 - Fatal Execution Engine Error (7A035E00) (80131506)
Soluzione? Ho disisntallato e reinstallato i PowerCommands come suggerito qui.
Technorati Tag:
VS2008 SP1
Immaginiamo di dover creare un processo che viene eseguito in un thread separato il quale genera eventi di notifica. Questi eventi devono essere intercettati e gestiti dall’interfaccia utente, per notificare informazioni sull’avanzamento del processo all’utente, oppure per iteragire con il proccesso stesso.
L’interfaccia è implementata da un applicazione Windows Form NET 3.5, mentre l’engine è in una class library separata.
Immaginiamo di avere una classe Engine, con un metodo Start e tre eventi che notificano l’avvio del processo, l’esecuzione del processo e il termine. Utilizzando come entry point del thread il delegato ParameterizedThreadStart, una prima implementazione potrebbe essere la seguente.
public class Engine
{
public void Start()
{
Thread thread = new Thread(EngineFunc);
thread.Start(this);
}
public event EventHandler OnStart;
public event EventHandler OnProcess;
public event EventHandler OnEnd;
static void EngineFunc(object Engine)
{
Engine engine = (Engine) Engine;
//Avvio
engine.RaiseEngineStart();
//Processo
engine.RaiseEngineProcess();
//Termine
engine.RaiseEngineEnd();
}
protected virtual void RaiseEngineStart()
{
if (OnStart != null)
{
OnStart(this, new EventArgs());
}
}
...
}
Questa implementazione apparentemente corretta funziona solamente se il codice eseguito dai gestori degli eventi non accede a risorse condivise che non implementino una gestione della concorrenza, oppure non interagisce con l’interfaccia utente. In quest’ultimo caso, se si tratta di Windows Forms, immaginando di voler segnalare l’avanzamento del processo all’utente attraverso una apposito controllo, riceveremo un eccezione System.InvalidOperationException che ci avverte : “Cross-thread operation not valid: Control 'txtLog' accessed from a thread other than the thread it was created on.”. Windows Forms controlla quindi che l’accesso alla risorse grafiche non avvenga da un thread secondario.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
engine.OnStart += new EventHandler(engine_OnStart);
...
}
private void Form1_Load(object sender, EventArgs e)
{
engine.Start();
}
void engine_OnStart(object sender, EventArgs e)
{
LogText("Processo avviato."); //Eccezione:System.InvalidOperationException
}
...
readonly Engine engine = new Engine();
}
L’eccezione viene generate, perchè come spiegato dal messaggio della stessa, viene controllato che l’accesso ai controlli di interfaccia venga effettuato dallo stesso thread di creazione del controllo. La soluzione immediata è quella di eseguire il delegato associato all’evento dal thread di esecuzione dell’interfaccia utente, per fare questo è sufficiente chiamare i metodi Invoke (sincrono) o BeginInvoke (asincrono) sulla Form, in modo da accodare l’esecuzione del codice al thread dell’interfaccia. Per implementare una soluzione immediata si possono utilizzare alternativamente gli anonymous delegate piuttosto che le lambda expression.
void engine_OnStart(object sender, EventArgs e)
{
//Anonymous method
this.BeginInvoke((MethodInvoker) (delegate
{
LogText("Processo avviato.");
}));
}
void engine_OnStart(object sender, EventArgs e)
{
//Lamda expression
this.BeginInvoke((MethodInvoker) (() => LogText("Processo avviato.")));
}
Entrambi le soluzioni funzionano correttamente. Pur essendo funzionale, l’architettura di questa soluzione non mi soddisfa: non è pratica se gli eventi sono molti e/o i gestori hanno una certa complessità. Inoltre volevo trovare una soluzione che astraesse questo problema rispetto alla specifica tecnologia di interfaccia utente.
Ho pensato quindi di rappresentare l’invocazione degli eventi, dal punto di visto del chiamante (engine) come un servizio, ed ho quindi definito il contratto astratto con un interfaccia.
public interface IInvoker
{
/// <summary>
/// Invocazione sincrona.
/// </summary>
/// <param name="method">Delegato</param>
/// <param name="args">Parametri</param>
void InvokeSyncEvent(Delegate method, params object[] args);
/// <summary>
/// Invocazione asincrona.
/// </summary>
/// <param name="method">Delegato</param>
/// <param name="args">Parametri</param>
void InvokeAsyncEvent(Delegate method, params object[] args);
}
Ora si modifica l'engine in modo da poter essere inizializzato, opzionalmente, con una referenza al servizio IInvoker appena creato. In alternativa la referenza al servizio può essere iniettata con un approccio IoC. Si crea un nuovo metodo che implementa l'invocazione sincrona di un evento standard (EventHandler) questo verificherà se è disponibile la referenza al servizio di invocazione, in questo caso utilizzerà quest'ultimo, altrimenti utilizzerà l'invocazione standard.
public class Engine
{
protected IInvoker _Invoker;
public Engine()
{
//Invocazione eventi standard
}
/// <summary>
/// Costruzione di engine con invoker specifico per gli eventi.
/// </summary>
/// <param name="Invoker">Referenza al servizio di invocazione degli eventi</param>
public Engine(IInvoker Invoker)
{
//Invocazione eventi via IInvoker
_Invoker = Invoker;
}
/// <summary>
/// Imposta il servizio di invocazione degli eventi
/// </summary>
public IInvoker Invoker {set { _Invoker = value; } }
...
protected virtual void RaiseEngineStart()
{
InvokeEvent(OnStart);
}
...
public void InvokeEvent(EventHandler EventHandler)
{
if (EventHandler != null)