Power user tools list
Che Scott Hanselman fosse un grande era ormai da tempo una questione fuori da ogni dubbio, ma il lavoro che ha presentato in questo suo post è davvero eccezionale: l’elenco di tutte le utility/tools è lista più completa che abbia mai visto.
Sto passando uno ad uno i link/applicazioni che non conoscevo e resto sempre colpito dall’aumento di produttività che queste possono comportare. Per fortuna mi consolo osservando che qualcuno già lo utilizzo con successo! Molto belle le sezioni dedicate allo sviluppo .Net e alle “Things Windows Forgot”.
Consiglio a tutti di “perderci” un po’ di tempo.
I pochi applicativi (free) che ho avuto tempo di installare sino ad ora sono:
.Net, class library e web services
Descriviamo un po’ la situazione in cui ci troviamo:
- abbiamo un web service (sviluppato in ASP.Net);
- vogliamo realizzare una libreria (class library .Net 3.5) per offrire una sorta di “interfaccia comune” verso il web service in modo tale che qualsiasi applicazione (in particolare applicazioni “stand alone” .Net) possa richiamare i servizi esposti senza troppi “grattacapi”.
Come si dovrebbe procedere: da Visual Studio (2008 SP1), nel progetto della nostra class library, si passa alla creazione di un “web-reference” (in relazione al web service in questione). Non serve fare altro: sulla carta non è necessaria alcuna particolare operazione sul progetto dell’applicazione che utilizza la nostra nuova class library. In realtà, se compilate ed eseguite il programma, potrete vedere da voi stessi che l’applicativo non è in grado di collegarsi al web service.
Qui di seguito il messaggio contenuto nell’eccezzione che viene generata quando tentate di accedere al web service: “Could not find default endpoint element that references contract ‘___’ in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.”
Motivo? Diciamo che i “riferimenti” o (entry point) al web service non vengono “copiati” dalla class library all’applicazione che la utilizza. Questi riferimenti sono contenuti nel file .config della class library (in dettaglio possiamo trovare tutte le informazioni all’interno del tag <system.serviceModel>). Il file .config della class libray, purtroppo, non “segue” la libreria nell’applicazione che la utilizza (se andate a vedere nella cartella bin del vostro applicativo, troverete solo il fiel .config relativo a quest’ultimo).
Il problema è aggirabile manualmente: basta copiare tutto il contenuto del tag <system.serviceModel> dal file .config della class library a quello dell’applicazione (operazione fattibile ma assai scocciante).
Qui di seguito un esempio della parte da copiare.
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="WebServiceSoap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://_/_.asmx" binding="basicHttpBinding" bindingConfiguration="WebServiceSoap" contract="_" name="_" /> </client> </system.serviceModel>
Per poter “scrivere” nel file .config dell’applicazione andate nel Solution Explorer del Visual Studio: tasto destro del mouse sul progetto in questione, andate alla voce Add nel menù che via appare ed a questo punto cliccate sulla voce New Item.

A questo punto vi apparirà una nuova finestra: selezionate General nella parte sinistra ed Application Configuration File in quella destra. Qui di seguito un’immagine che illustra le operazioni appena elencate.

Bene! Tutto il contenuto del nuovo file .config (che ritroverete nella lista dei file del vostro progetto) sarà ricopiato nel file .config “ufficiale” dell’applicazione.
Il problema sembra essere ben conosciuto, ma al momento non ho letto ancora nulla in merito ad una sua soluzione nel futuro Visual Studio 2010. Ho letto che la gestione dei file .config è stata migliorata permettendo una sorta di “diversificazione” tra debug e release, ma nulla circa il problema qui sopra evidenziato.
Dertiminare/verificare se un path (stile Microsft Windows) è assoluto (in C#)
Sembra una stupidaggine, ma una funzione esplicita per fare questo non esiste, o meglio, non funziona proprio come si deve.
Il metodo del Microsoft .Net frame work in questione è Path.IsPathRooted. Sono riuscito a scovare questa funzione grazie a questo post. Ma più che il post in se stesso, la cosa più interessante è il primo commento che apapre nella pagina: la funzione Path.IsPathRooted considera il path “\temp\” come assoluto!
Diciamo che la cosa non va per nulla bene! Sebbene ci abbia perso un po’ di tempo, non sono riuscito a trovare una spiegazione al caso.
Date le circostanze, si è reso necessario sviluppare un’apposita funzione che svolga il lavoro: qui di seguito il codice.
public static bool isAbsolutePath(string sPath)
{
string sPattern = @"^[a-zA-Z]:\\";
Regex R = new Regex(sPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
return R.IsMatch(sPath);
}
Per compilare il tutto, ricordarsi di includere il namespace System.Text.RegularExpressions.
Attenzione che la funzione non determina se un path è sintatticamente corretto (vedere post precedente): si limita a verificare “come inizia” per capire se è assoluto o meno. Il funzionamento è poi limitato solo a path locali alla macchina: non vengono gestiti path UNC.
Verificare la correttezza sintattica dei path con .Net
Pochi giorni fa mi sono imbattuto nel seguente problema: verificare che una certa stringa contenga un path (di file o directory) valido o corretto. Ho scoperto che molti sviluppatori confondono la correttezza o validità con l’esistenza o meno della “risorsa” (file o directory) “descritta” dal path stesso. La correttezza o validità sintattica del path è, ovviamente, “platform dipendente”. Un path valido per la piattaforma GNU/Linux non lo è di certo per la piattaforma Microsoft Windows!
Esempio di path (assoluto) valido per piattaforma Microsoft:
c:\pippo\pluto\paperino
Esempio di path (assoluto) valido per piattaforma GNU/Linux:
/home/house/flat
Non è detto che la risorsa “descritta” da un path esista o no, ma i due esempi in precedenza esposti sono sicuramente sintatticamente corretti (per le rispettive piattaforme indicate). Ora, com’è possibile verificare la correttezza sintattica di un path nella piattaforma Microsoft ed utilizzando il framework .Net? In rete si trova un po’ di tutto, soprattutto si capisce, come accennavo all’inizio, che molta gente non è capace di inquadrare il problema.
Esempio di path (assoluto) non valido per piattaforma Microsoft:
hug:\\\pippo\\pluto\paperino
Una soluzione possibile è quella di utilizzare le regular expression: non così banale però definire la regola corretta! Quelle che ho trovato in rete sono di certo incomplete: un path può essere assoluto o relativo! Un soluzione veloce, forse non troppo elegante è quella che vi propongo qui di seguito.
private bool checkPathValidity(string sPath)
{
try
{
new FileInfo(sPath);
return true;
}
catch
{
return false;
}
}
Al fine di far funzionare correttamente il tutto, vi ricordo di includere il namespace System.IO (che definisce FileInfo).
Sebbene, dal mio punto di vista, non è buona cosa utilizzare l’occorrenza o meno di un’eccezione per determinare lo “stato” di qualcosa, la soluzione proposta è sicuramente completa e corretta. Mi riservo su eventuali problemi di concorrenza: al momento non riesco a trovarne, ma è meglio sempre mettere le mani avanti su queste cose!
C#’s const vs. readonly
È da un po’ che mi chiedevo quale fosse la differenza tra le due keyword c# const e readonly. Ho trovato un interessante post di Patrick Steele che spiega sinteticamente ed esaustivamente le peculiarità di queste due parole riservate.
Qui di seguito ne riporto la traduzione in italiano.
Una variabile definita const:
- non può essere anche static;
- il suo valore è determinato in fase di compilazione;
- può essere inizializzata solo nella sua dichiarazione.
Una variabile definita readonly:
- può essere anche static;
- il suo valore è determinato a run-time;
- può essere inizializzata sia nella sua dichiarazione che dal costruttore della classe.
Più che evidente che le due keyword non sono proprio così intercambiabili.
WindowsForms e chiusura dell’applicazione
Della serie “non si finisce mai di imparare”.
L’argomento in questione sono le WindowsForm del framework Microsoft .NET. Il soggetto, nel dettaglio, la funzione Application.Exit.
Ieri ho scoperto che invocare la funzione sopra citata all’interno del costruttore della finestra non porta ai risultati per cui la funzione è stata realizzata. A pensarci un attimo la cosa è anche ovvia, ma al momento di scrivere il codice, quasi mai affiorano alla mente gli eventuali “back side effects”.
Qui di seguito il codice originale.
using System;
using System.Windows.Forms;
namespace test
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
try
{
// ...
}
catch(Exception)
{
Application.Exit();
}
}
}
}
Come aggirare la cosa? Abbastanza semplice, e direi anche, molto spesso la via è facilmente percorribile: basta spostare il nostro codice “incriminato” nella funzione “allacciata” all’evento load della form stesa. All’interno di questo evento il metodo exit funziona correttamente in quanto, una volta che il costruttore della classe form ha terminato, la coda dei messaggi è attiva e, finalmente, può processare il messaggio generato dalla exit.
Qui di seguito il codice aggiornato.
using System;
using System.Windows.Forms;
namespace test
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
}
private void FormMain_Load(object sender, EventArgs e)
{
try
{
// ...
}
catch(Exception)
{
Application.Exit();
}
}
}
Asynchronous Method Invocation
Ho appena scovato in The Code Project un articolo veramente ben fatto che, in poche parole, illustra come invocare in modo asincrono un delegate.
L’articolo è veramente ben fatto e, tra le altre cose, mette bene in evidenza quali sono i limiti del sistema descritto.
Potete trovare l’articolo a questo link.
Libro: “patterns & practices Application Architecture Guide 2.0″
Segnalo con piacere la possibilità di scaricare gratuitamente alla seguente pagina, il libro “patterns & practices Application Architecture Guide 2.0”. Si tratta di un “vecchio” libro (se non sbaglio la prima versione risale al 2001) che è stato riadattato e rivisto per adeguarsi alle novità apportate dal Microsoft .Net framework.
Non l’ho ancora letto, ma mi sono imposto di farlo a breve!
…ancora sulla classe Process (System.Diagnostics)
Della serie: quando ci si aspetta che le cose funzionino in ben altro modo!
In sostanza, quando lanciamo dalla nostra applicazione .Net un altro processo tramite la classe Process, possiamo benissimo “schematizzare” il funzionamento come un thread che controlla l’andamento del programma concorrente.
Consideriamo il seguente codice allora.
OtherProcess = new Process();
OtherProcess.StartInfo.FileName = "OtherProcess.exe";
OtherProcess.StartInfo.Arguments = "/someParameters";
OtherProcess.Exited += delegate(object sender, EventArgs e) { otherProcessTerminated(); };
OtherProcess.EnableRaisingEvents = true;
OtherProcess.Start();
Nella situazione sopra proposta, una volta che l’applicazione OtherProcess.exe termina verrà lanciato l’evento Exited che porterà all’esecuzione del relativo delegate e, per finire, alla chiamata della funzione otherProcessTerminated.
E fin qui nulla da obbiettare. La domanda è: in che modo viene “gestito” l’evento? Mi sarei aspettato che venisse messo in coda e processato ordinatamente (nel Main thread) dopo quanti lo precedevano. In realtà ciò non avviene, ma è lo stesso thread creato appositamente dalla classe Process che si prende in carico anche l’esecuzione del delegate, generando delle “race condition” che portano a side effects quasi mai considerati in fase di sviluppo.
Come poter aggirare la cosa, che risulta assai sgradevole se si è fatto di tutto al fine di evitare problemi di concorrenza? Molto semplice: prima di invocare il metodo Start, aggiungete la seguente linea di codice.
OtherProcess.SynchronizingObject = this;
Ovviamente il puntatore this dovrà far riferimento ad un controllo WindowsForm in grado di “gestire” i messaggi (per dirlo con terminologia Win32).
Qui la documentazione relativa alla proprietà SynchronizingObject della classe System.Diagnostics.Process.
P.s.: per questo post si ringrazia il Sig. Botsutoshi per il suo indispensabile contributo.











