lunedì 13 dicembre 2010

Unable to start debugging

Alcuni giorni fa’ mi sono imbattuto in un problema abbastanza strano. Di colpo VS2008 non riusciva più a eseguire il debug di un’applicazione C++ su Windows CE riportando l’errore sibillino “unable to start debugging”. Come prima cosa ho incolpato il device che stavo utilizzando e sono passato su un altro tipo di device. Niente, stesso errore.

Dopo parecchi minuti spesi in rete per cercare qualche lume inizio a leggere un po’ di post che parlano di qualche effetto collaterale dovuto all’installazione di phone 7 SDK su VS2010.

In effetti, il codice su cui stavo cercando di eseguire il debug l’avevo scritto qualche mese fa, prima di installare tutto l’ambiente per windows phone 7. Cercando meglio nei post scopro che è legato proprio all’installazione di tale ambiente.

Soluzioni ? Disinstallare VS2010 e/o reinstallare VS2008 ? Sono da clienti e di certo non posso permettermi di fare una cosa del genere!

Scavando meglio in rete trovo altre persone che hanno lo stesso problema. Umm, nessuna soluzione se non reinstallare i vari ambienti di sviluppo.

Alla fine trovo un post di Raffaele Limosani che spiega come effettuare un work-around “temporaneo” ed “accettabile”:

1. rinominare la cartella C: \ Program Files \ Microsoft Visual Studio 10.0 \ SmartDevices \ Debugger \ target \ wce400 \ ARMV4i in .. \ armv4i_temp

2. copiare la cartella C: \ Program Files \ Microsoft Visual Studio 9.0 \ SmartDevices \ Debugger \ target \ wce400 \ ARMV4i all'interno del percorso di Visual Studio 2010.

Funziona !!!

Comunque, come sempre di fronte a certe cose, non penso servano commenti.

lunedì 6 dicembre 2010

Codice e slide della sessione “Da Windows Mobile 6.5 a Windows Phone 7”

Ecco disponibili al download, il codice e le slide del XeDotNet community meeting che ho tenuto il 03 Dicembre 2010 dal titolo Da Windows Mobile 6.5 q Windows Phone 7.

In questa sessione affronteremo le differenze principali tra le due versioni del s.o. Windows Mobile esplorando sia gli strumenti di sviluppo che le architetture. Verranno illustrati i punti in comune e non per preparare i nostri applicativi al passaggio verso il nuovo s.o. Nella sessione saranno esplorati poi i dettagli dell'architettura su cui si basa il nuovo s.o. Windows Phone

Volevo porgere un ringraziamento a tutte le persone presenti al meeting ed in particolare ad Andrea Boschin per il supporto “tecnico e morale” e la condivisione della sessione. Grazie ancora a XeDotNet per l’opportunità che mi è stata data.

venerdì 22 ottobre 2010

XE.NET: Mobile Track

 

Da Windows Mobile 6.5 a Windows Phone 7 Series
In questa sessione affronteremo le differenze principali tra le due versioni del s.o. Windows Mobile esplorando sia gli strumenti di sviluppo che le architetture. Verranno illustrati i punti in comune e non per preparare i nostri applicativi al passaggio verso il nuovo s.o. Nella sessione saranno esplorati poi i dettagli dell’architettura su cui si basa il nuovo s.o. Windows Phone.
Speaker: Mirco Vanini – Senior Consultant

Creare applicazioni per Windows Phone 7 Series con Silverlight
In questa sessione affronteremo lo sviluppo con Windows Phone 7, con particolare riguardo alla realizzazione di applicazioni con Silverlight, lo strumento principale per lo sviluppo su questo nuovo dispositivo. La sessione indicherà come predisporre l'ambiente di sviluppo, quali sono gli strumenti di sviluppo e le basi da cui iniziare.
Speaker: Andrea Boschin (MVP Silverlight)

Data: Venerdì 3 Dicembre 2010
Ore: 19.30
Luogo: Novotel Venezia Mestre Castellana – Via Alfredo Ceccherini 21 – 30174 Venezia Mestre

Iscrizione

XE.NET: Virtual Meeting–F#

 

Iniziare con F#
In Visual Studio 2010 è apparso un nuovo linguaggio: F#. Cos'è, da dove nasce, come si scrive in F#. E perchè tanti lo stanno apprezzando più di C#...
Speaker: Marco Parenzan

Registrazione: 21:00:00
Inizio: 21:30:00
Località: Live Meeting online

Iscrizione

XE.NET: Microsoft Community Tour 2010/2–17.11.2010

 

09:30 – Keynote
Speaker: Lorenzo Barbieri - Microsoft Developer Evangelist

10:10 - Windows Phone 7: Sviluppare applicazioni per il Marketplace
In questa sessione vedremo lo sviluppo di applicazioni per il Marketplace di WP7, con esempi presi da applicazioni reali.
Speaker:  Lorenzo Barbieri - Microsoft Developer Evangelist 

11:35 - Make javascript Simple with jQuery
La costante richiesta di interfacce rich nella applicazioni internet sta spingendo sempre più l'adozione di librerie Javascript che facilitino la programmazione con questo linguaggio che per molti versi è ostico, almeno quanto flessibile. jQuery ormai si è guadagnato la palma di migliore e maggiormente adottata libreria, con un core molto snello e una serie di plugin di grande efficacia che aiutano molto il programmatore quando l'ambiente non consente l'uso di più moderni strumenti RIA. In questa sessione affronteremo jQuery, cercando di comprendere i principi che stanno alla base del suo funzionamento vedendoli applicati in un piccolo gioco sviluppato in appena 100 righe di codice. Vedremo come jQuery porti sollievo a molti dei problemi di Javascript e perchè no anche quali sono i confini entro cui la sua efficacia viene meno.
Speaker: Andrea Boschin - MVP Silverlight

14:15 - Windows Azure: Getting Started
Iniziamo a mettere la testa tra le nuvole esplorando l'offerta Microsoft per il Cloud Computing. Windows Azure, SQL Azure e Windows Azure AppFabbric offrono allo sviluppatore un modo nuovo di disegnare le proprie applicazioni garantendo maggior disponibilità, scalabilità e manutenibilità a costi inferiori rispetto a quanto ottenibile con approcci di sviluppo e distribuzione tradizionali. Cosa sono e come si utilizzano sono gli aspetti su cui si baserà questa sessione con l'intento finale di mostrare ai partecipanti come iniziare a utilizzare questa piattaforma.
Speaker: Davide Vernole – MVP Visual Studio ALM

15:25 - XBAP Application with WPF 4.0
Le applicazioni browser XAML (XBAP) combinano le funzionalità delle applicazioni Web e delle applicazioni rich client. In modo analogo alle applicazioni Web, le applicazioni XBAP possono essere distribuite in un server Web e avviate da Internet Explorer o Firefox. Come le applicazioni rich client, le applicazioni XBAP possono trarre vantaggio dalle funzionalità di WPF. In questa sessione vedremo un'introduzione allo sviluppo di applicazioni XBAP e vengono illustrate le differenze esistenti tra lo sviluppo di questo tipo di applicazioni e lo sviluppo di applicazioni rich client standard.
Speaker: Davide Senatore - MVP Client App Dev

16:50 - Potenzialità e benefici di ASP.NET MVC
ASP.NET MVC è un framework sviluppato da Microsoft che permette lo sviluppo di applicazioni web utilizzando il pattern Model-View-Controller. Questo pattern si propone di apportare alcuni benefici: maggiore controllo del markup della pagina, URL più leggibili, facilità di integrazione con librerie javascript, chiara separazione dei ruoli/responsabilità tra layer, testabilità e manutenzione del codice... In questa sessione cercheremo di capire quali siano gli effettivi vantaggi che ASP.NET MVC porta agli sviluppatori, e quindi capire, con un occhio pratico, quali reali benefici si abbiano nell'adottare questa tecnologia.
Speaker: Andrea Dottor - MVP ASP.NET

Registrazione: 09:00:00
Inizio: 09:30:00
Località: Hotel Holiday Inn, Marghera (VE)

Iscrizione

XE.NET: Quality Track

 

Microsoft Test Manager
Pianificare, testare e tracciare le attività di testing non è mai stato così completo. Visual Studio 2010 introduce un nuovo approccio alle attività compiute dai tester di applicazioni facilitando la stima di questa delicata parte del ciclo di vita del software. Durante la sessione impareremo a conoscere un nuovo compagno di avventura, Microsoft Test Manager (MTM), in grado di risolvere molti dei problemi che hanno da sempre afflitto il processo di test e bug fixing. Perfettamente integrato con Team Foundation Server 2010 è destinato ad essere uno strumento indispensabile per la creazione di software di qualità.
Speaker: Davide Vernole (MVP Visual Studio ALM)

Ottimizzazione di un'applicazione ASP.NET
Nelle applicazioni di tutti i giorni, spesso ci scontriamo con problemi di performance, oppure siamo alla ricerca di un miglioramento che possa rendere più reattiva la nostra applicazione. In questa sessione vedremo come grazie all'utilizzo della cache, session, ed altri strumenti, possiamo ottimizzare il nostro sito fornendo un feedback migliore all'utente. Con esempi pratici, vedremo il beneficio di come semplici accortezze potranno migliorare notevolmente un'applicazione. Cache, session, IIS 7, routing...saranno i principali argomenti trattati.
Speaker: Andrea Dottor (MVP ASP.NET)

Data: Giovedì 4 Novembre 2010
Ore: 19.30
Luogo: Novotel Venezia Mestre Castellana – Via Alfredo Ceccherini 21 – 30174 Venezia Mestre

Informazioni - Iscrizioni

domenica 17 ottobre 2010

A volte ritornano…

Dopo molti mesi ritorno a scrivere sul blog, nuovo blog e nuova avventura. Per una serie di circostanze sia familiari sia lavorative non ho più curato quest’attività, non ultimo la chiusura inattesa e non conosciuta del blog ugimobile che mi ospitava. Grazie all’aiuto di Andrea sono riuscito a recuperare un po’ di articoli che avevo scritto nel tempo, perdendone tanti tanti altri. Sinceramente non capisco il comportamento di alcune persone e le motivazioni che hanno portato alla chiusura di ugimobile, ma questa è un’altra storia. Bene non mi resta che tirarmi su le maniche e riiniziare a scrivere.

.NET Micro Framework 4.0 Download

Alcuni giorni fà è stata rilasciata la versione 4.0 del .NET Micro Framework. Questa è la prima release dopo il trasferimento del gruppo sotto la Developer Division. La versione ha un certo numero di nuove funzionalità. In questo link potete trovare la lista completa.

Il donload è diviso in diversi pacchetti, in dettaglio:

Penso che sia la risposta più “concreta” a chi dava il progetto Micro FW sul viale del tramonto.

Microsoft Silverlight for Windows Embedded

Con il rilascio di Windows CE SR3 una delle features più interessanti è la disponibilità di Silverlight for Windows Embedded. Attenzione è un UI framework che si basa su API Win32/nativo e non su codice gestito. 

WiFi 802.11 Wireless for .NET Micro FW

GHI ha annunciato il primo modulo hardware “Micro Famework WiFi Expansion” che rende disponibile una connessione WiFi su .Net Micro FW 3.0. Il nuovo modulo supporta WEP, WPA, WPA2 attraverso la cifratura hw AES e RSA. il modulo è disponibile per i seguenti prodotti di GHI: ChipworkX ed Embedded Master

“Expert .NET Micro Framework” – Second edition

E’ disponibile la seconda edizione del libro “Expert .NET Micro Framework” di Jens Kühner. (ApressAmazon)

VS2008: Errore connessione a un dispositivo Windows CE senza ActiveSync

Chi sviluppa su device Windows CE avrà sicuramente letto ed utilizzato la procedura per stabilire una connessione verso un dispositivo Windows CE senza ActiveSync riportata nel seguente articolo (Procedura stabilire una connessione a un dispositivo Windows CE senza ActiveSync). Niente da dire, anzi se non che dopo l'installazione di VS 2008 sullo stesso PC in cui è installato VS 2005 ogni tentativo di stabile una connessione verso il device riporta i seguenti errori:

VS 2005 Connection failed:0x8973151A

VS 2008 Connection failed: The version of Comman client running on the device is incompatible with the desktop. Boostrap the device with desktop compatible device binaries and try connectiong again.

Dopo alcuni tentativi e ricerche infruttuose su internet ho trovato il bandolo della matassa. La parte inerente il device emulator di VS 2008 non è installabile side by side, in altre parole la versione di VS 2005 viene sovrascritta da quella di VS 2008.

Per ovviare il problema basta copiare nel dispositivo i files aggiornati da VS 2008 contenuti nel percorso.

C: \Programmi\File comuni\Microsoft Shared\CoreCon\1.0\Target\wce400\<CPU>

Embedded Master Development System

Finalmente è arrivata!

Alla fine mi sono deciso a comprarla (GHI Electronics - Embedded Master Development System), l'ho aperta da qualche giorno e devo dire che il rapporto qualità prezzo mi ha soddisfatto. La confezione si presenta scarna ma il "contenuto" è sicuramente all'altezza delle aspettative.

Dopo l'installazione del .NET Micro Framework ho ovviamente installato EmbeddedMasterSDK della scheda, non presente nella confezione ma scaricato dal sito. Il setup è andato al primo colpo senza intoppi e/o sorprese. La documentazione e gli esempi forniti nel SDK sono sufficientemente completi, anche se come al solito la documentazione non è mai abbastanza :)

Dopo un pò di prove con il .NET Micro Framework Deployment Tool sono riuscito a stabilire la connessione tra il PC e la scheda. L'unico intoppo l'ho trovato nell'installazione del Virtual Com Port Drive per la parte di debug, dopo vari tentati di collegamento andati a vuoto ho scoperto che dovevo cambiare il tempo di latenza (da 16 msec a 1 msec) nell'impostazioni della USB Serial Port.

Ho scaricato poi le varie patch sia del TinyBooter e del TinyCLR dal sito del costruttore della scheda e le ho installate senza grossi problemi. Gli steps per l'upgrade sono spiegati in dettaglio nella documentazione del SDK.

Ho poi caricati gli esempi forniti con SDK, compilati, distribuiti e debbugati direttamente sulla scheda. Anche l'emulatore fornito con SDK non è malaccio, tanta scena ma manca tutta la gestione degli I/O della scheda. Sarebbe stato comodo avere un sistema di emulazione degli I/O senza andare per forza su HW

Bene, adesso sono finalmente pronto a scrivere il mio primo programma su .NET Micro FW.

Expert .Net Micro Framework

Dopo aver acquistato il kit di sviluppo GHI Electronics - Embedded Master Development System ho pensato bene di acquistare un libro dedicato al .NET Micro Framework. Devo dire che sul mercato non c'è tantissimo e alla fine ho deciso di acquistare il libro di Jens Kühner - Expert .Net Micro Framework. Devo dire la verità, sin dall'inizio mi è piaciuto.

Essendo un amante dei libri cartacei ricevere un libro con copertina rigida, rilegato in modo che non si sfaldi dopo le seconda lettura e stampato su della carta di qualità discreta fa solo che piacere. Oltre all'impressione "estetica" e "fisica" devo dire che è un buon libro, strutturato bene, che prende per mano il lettore e lo porta ad esaminare le varie parti del .Net Micro FW.

Si parte dalla genesi del Micro FW, ne descrive le varie parti costituenti e fà una rapida carellata sui kit di sviluppo attualmente disponibili. Questa è solo l'introduzione del libro, poi si passa alla "sostanza". Descrive in modo accurato la gestione delle varie porte hardware, il threading disponibile, la crittografia, la comunicazione via socket, per poi arrivare al DPWS (Device Profile for Web Service). Devo dire che forse è il capitolo che mi ha entusiasmato di più, anche se per poterlo utilizzare si deve scrivere un bel pò di codice.

Si arriva poi alla gestione della localizzazione e sopratutto alla parte di gestione grafica e di user interface. Anche questo capito è degno di nota sopratutto per i semplici ma efficaci esempi riportati.

Ultima parte ma non per questo meno importante è la gestione dell'emulazione hardware e dei relativi componenti. Ben scritta e documentata sopratutto negli esempi di implementazione di componenti per l'emulazione hardware.

Che dire ? Sicuramente è un libro ben fatto ed indispensabile per chi vuole partire ed approffondire lo sviluppo con .Net Micro FW.

Buona lettura a tutti

 

Technorati Tag: ,

AddHeader - ISAPI

Durante lo sviluppo di una ISAPI filter mi è capitata la necessità di creare una variabile server IIS durante la gestione della notifica SF_NOTIFY_AUTHENTICATION.

Peccato che in questa notifica il parametro pvNotification passato da IIS sia di tipo PHTTP_FILTER_AUTHENT e non vi sia il modo di recuperare la struttura di tipo PHTTP_FILTER_PREPROC_HEADERS che contiene il metodo AddHeader.

Dopo un po' di tentativi ho percorso questa strada:

 

1. Definisco i seguenti typedef e define

   1: #define MYISAPI_HEADER       "MYISAPI-HEADER:"
   2: #define HTTP_MYISAPI_HEADER    "HTTP_MYISAPI_HEADER"
   3:  
   4: typedef BOOL (WINAPI * PAddHeader) 
   5:               (
   6:                 struct _HTTP_FILTER_CONTEXT * pfc,
   7:                 LPSTR                         lpszName,
   8:                 LPSTR                         lpszValue
   9:               );

2. Nella notifica SF_NOTIFY_PREPROC_HEADERS creo una variabile server che contiene l'indirizzo del metodo AddHeader come nel codice seguente



   1: TCHAR szTmp[256];
   2: sprintf_s(szTmp, sizeof(szTmp), "%08lx", ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->AddHeader);
   3: if(((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->HttpStatus == 0)
   4: {
   5:     TCHAR szValue[256];
   6:     DWORD dwValue = sizeof(szValue);
   7:  
   8:     *szValue = 0;
   9:     ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->GetHeader(pfc, MYISAPI_HEADER, szValue, &dwValue);
  10:  
  11:     if(*szValue == 0)
  12:         ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->AddHeader(pfc, MYISAPI_HEADER, szTmp);
  13: }
  14: return(SF_STATUS_REQ_NEXT_NOTIFICATION);

3. Nella notifica SF_NOTIFY_AUTHENTICATION utilizzo la variabile server creata precedentemente nella notifica SF_NOTIFY_PREPROC_HEADERS, eseguo il cast su il pointer a funzione definito nel typedef e la richiamo per impostare una nuova variabile server



   1: TCHAR szValue[256];
   2: DWORD dwValue = sizeof(szValue);
   3:  
   4: *szValue = 0;
   5: pfc->GetServerVariable(pfc, HTTP_MYISAPI_HEADER, szValue, &dwValue);
   6: if(*szValue != 0)
   7: {
   8:     try
   9:     {
  10:         PAddHeader pHeader = (PAddHeader)strtoul(szTmp, NULL, 16);
  11:         if(pHeader)
  12:            (pHeader)(pfc, MYISAPI_USER_ID_LDAP, W2A(pszUidLdap));    
  13:     }
  14:     catch(CException *e)
  15:     {
  16:         DumpException(e)
  17:         e->Delete();
  18:     }
  19: }

 


Funziona :)

System Meter Chart PDA

Durante lo sviluppo di un progetto mi sono imbattuto nella necessità di realizzare un controllo per PDA che rapresentasse l'andamento di un valore nel tempo. Come "fonte di ispirazione" ho utilizzato la visualizzazione della "cronologia utilizzo CPU" del task manager.

Dopo un pò di lavoro sono riuscito a "confezionare" un controllo che ne mima il comportamento. Ho esteso un pò il grafico prodotto permettendo la gestione dello stesso sia tramite line che stick.

Il controllo utilizza un sistema di  "Double Buffering" con una bitmap offline in cui viene effettivamente disegnato il grafico. Questo ovviamente per evitare il flickering che inevitabilmente sarebbe comparso.

Tutto questo perchè su .Net CF i controls non supportano il double buffer nativamente, per esempio in .Net è possibile attivarlo tramite il seguente codice:

   1: public void EnableDoubleBuffering()
   2: {
   3:    // Set the value of the double-buffering style bits to true.
   4:    this.SetStyle(ControlStyles.DoubleBuffer | 
   5:                  ControlStyles.UserPaint | 
   6:                  ControlStyles.AllPaintingInWmPaint,
   7:                  true);
   8:    this.UpdateStyles();
   9: }

Di seguito riporto un print screen del programma demo e il link in cui trovare il medesimo.



 


Sorgenti Progetto di esempio


Buone "misurazioni" a tutti :)

ActiveSync - GuestOnly

Chi collega e scollega device tutto il giorno al proprio PC, si sarà chiesto se vi è la possibilità di disattivare la richiesta di creazione relazione da parte di ActiveSync. Sicuramente l'impostazione di relazione va bene per sincronizzare mail, appuntamenti, ecc. ma non sicuramente per le sessioni di debug.

Ecco allora la chiave del registry da modificare:

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows CE Services]
"GuestOnly"=dword:1

Ovviamente per ripristinare la richiesta di relazione basta impostare "GuestOnly a 0 (zero)

Community Meeting - .NET Compact Framework

Volevo ringraziare tutti i partecipanti, Xe.Net ed 1nn0va per l'opportunità che mi hanno concesso. A breve metterò in linea il materiale del meeting.

Come sempre un ringraziamento "speciale" ad Andrea Boschin per il supporto materiale e morale.

DLL - Import

Se dovete collegare codice nativo e/o Win32 API a C# / VB.NET consiglio vivamente questo sito.

System Meter Chart – .Net Micro Framework

Finalmente in questi giorni di “festa” sono riuscito a trovare qualche ora di calma da famiglia, figlie, clienti, rogne, ecc. per effettuare il porting del controllo System Meter Chart da .NET Compact Framework (CF) a .NET Micro Framework (MF). Questa è stata una buona occasione per “toccare con mano” le diversità tra i due ambienti per quello che riguarda la progettazione di user control. Il .NET MF supporta una versione ridotta (molto) di WPF e la gestione / progettazione dei controlli ovviamente è diversa tra i due ambienti. Nel caso specifico (.NET MF) ho implementato un Control (UIElement) che si espone come oggetto WPF. 

 

Nelle applicazioni MF con presentation esistono due thread, il primo creato del programma per la gestione degli I/O, periferiche, ecc. mentre il secondo è creato ed utilizzato internamente dal CLR per le varie operazioni di UI (ridisegno degli elementi di UI come i controlli, le finestre, ecc.). Questo secondo thread è chiamato anche Dispatcher e il suo scopo è quello di accedere in modo “sicuro” ai vari elementi della UI. Per maggiori informazioni vi consiglio di leggere 'Using the Dispatcher’.

L’esempio di utilizzo del controllo usa un timer per l’assegnazione di valori random da 0 a 100. Essendo il timer asincrono rispetto all’interfaccia utente, per le operazioni di invalidate interne del controllo, è necessario chiamare BeginInvoke  per far si che il controllo grafico sia acceduto dal thread principale. La scelta di BeginInvoke è preferibile rispetto a Invoke così da poter liberare il thread del timer al più presto senza attendere il termine dell’esecuzione del gestore dell’evento.

L’esempio utilizza i 5 tasti presenti nell’emulatore del .NET MF, in dettaglio:

  • Tasto Up abilita la visualizzazione in “Stick Mode”
  • Tasto Down abilita la visualizzazione in “Line Mode”
  • Tasto Left abilita la visualizzazione in “NoGrid”
  • Tasto Right abilita la visualizzazione in “Grid”
  • Tasto Select abilita / disablita la visualizzazione del Gradient

Di seguito riporto alcune immagini delle modalità supportate dal controllo

 

Non nego che sono sempre più entusiasta del MF, penso solo a quanto codice avrei dovuto scrivere per realizzare lo stesso controllo su un’altra tipo di scheda non MF magari con un compilatore C++ proprietario. Seconda osservazione, la portabilità del codice da una piattaforma MF all’altra, infatti nell’esempio non ho utilizzato nulla di proprietario della mia scheda GHI ma solo chimate “standard” del MF 3.0. Come ultimo punto vorrei rimarcare l’integrazione del MF con Visual Studio,  si riesce a sviluppare ed eseguire il debugging dell’applicazione sia con l’emulatore che direttamente sulla scheda collegata via USB. Questo permette l’analisi sotto debugger di scenari che difficilmente sarebbero ripetibili tramite un emulatore e con una serie di comodità come solo i progammatori di Visual Studio sono abituati.  Ovviamente le schede che supportano MF non sono schede su cui la battaglia si gioca sui centesimi ma quello che da a disposizione MF ripaga anche il relativo costo.

In questo link potete scaricare lo zip dei sorgenti del programma di esempio.

GDI – Leak – WinCE – C#

Suona strano avere dei memory leak in codice gestito ma sono molto più frequenti di quello che si possa pensare. Alcune settimane fà ho tenuto una sessione di code review presso un mio cliente e ho speso alcuni giorni a sistemare diversi memory leak su una programma scritto in C# per Windows CE.

Quello che bisogna tenere a mente che tutti gli oggetti GDI (Bitmap, Font, Brush, Pen, ecc.) di C# in realtà sono dei wrapper sopra oggetti Win32. Tali oggetti sono referenziati tramite Handle e devono essere rilasciati. Il GC non lo fà per voi in modo automatico perchè semplicemente non li può gestire. Sopratutto nelle applicazioni mobile, in cui le risorse sono limitate, bisogna porre particolare attenzione a questo.

Durante la sessione di debug ho utilizzato questo tool (GDIView) che mi ha aiutato a verificare quali handle non venivano rilasciati.

Alcuni consigli pratici:

  • Richiamare sempre il Dispose di tutti gli oggetti grafici utilizzati, meglio ancora usare sempre la keword “using” per richiamare sempre in modo implicito il Dispose, esempio:
   1: SolidBrush fillBrush = new SolidBrush(Color.White);
   2: graphImage.FillRectangle(fillBrush, 0, 0, UI_CLIENT_WIDTH, UI_HEIGHT);
   3: fillBrush.Dispose();
   4:  
   5: // or
   6:  
   7: using(SolidBrush fillBrush = new SolidBrush(Color.White))
   8: {
   9:     graphImage.FillRectangle(fillBrush, 0, 0, UI_CLIENT_WIDTH, UI_HEIGHT);
  10: }
  11:  

 



  • Quando si riassegna una Bitmap assicurarsi che l’oggetto precedente sia deallocato, esempio:


   1: // wrong
   2: picCapture.Image = new Bitmap(32, 32);
   3:  
   4: // good
   5: if(picCapture.Image != null)
   6:     picCapture.Image.Dispose();
   7: picCapture.Image = new Bitmap(32, 32);

 



  • Quando si utilizza una Image contenuta in una ImageList è bene ricordare quanto esposto su MSDN: “The returned bitmap is a copy of the original image and should be disposed of using the Image.Dispose method.”. In altre parole tutte le get da una ImageList clonano una nuova immagine che deve essere rilasciata tramite un Dispose!
  • Quando si utilizzano direttamente le funzioni native Win32 porre attenzione se queste ritornano una nuova istanza di una risorsa in memoria. Leggere attentamente la loro documentazione!
  • Ogni volta che si alloca memoria tramite funzioni native Win32 è vostra responsabilità deallocarla.
  • Quando si crea un nuovo oggetto non gestito, salvare il riferimento (handle) in una variabile non accessibile dall’esterno. Se per qualsiasi motivo il riferimento viene sovrascritto non sarà più possibile deallocare correttamente la risorsa non gestita.