Tips & Tricks
Roberto Brunetti
[email protected]
http://thinkmobile.it/blogs/rob
Marco Frontini
[email protected]
http://thinkmobile.it/blogs/front
Architettura
• Mai scrivere il codice nel Click !!!!!!!!
• Dopo i controlli sull’interfaccia specifica
• Chiamare una classe che esegue il lavoro
• Occhio al numero di oggetti caricati
• Non usare GC.Collect()
• Implementare IDisposable dalle classi che fanno
uso di altre risorse
• Usare .Dispose() dal chiamante (o using)
• Come si fa per Connection al db, File etc etc
Uso Corretto try/catch
• Usare try/finally all’interno di try/catch:
try
{
File.Open()
try
} {
catch (FileNotFoundException
File.Open()
e)
{ }
MessageBox.Show(“Casino
finally
sul file”);
} {
finally
File.Close
{ }
}
File.Close
catch
}
(FileNotFoundException e) {
MessageBox.Show(“Casino sul file”);
}
Close / Minimize
• I form si minimizzano (X)
• Come le applicazioni CE
• Share Violation da VS mentre copia dell’exe
• Molte utility intercettano la X per chiudere
effetttivamente l’applicazione (form)
• PocketPlus / Pocket Controller
• Restando in memoria
• MinimizeBox = false
• Mette OK nella ControlBox
• Chiude la form
• Non Logo-Compliant !
Stop Close
• Per applicazioni sempre attive e bloccanti
• Intercettare Form.Closing
• (System.ComponentModel.CancelEventArgs e)
• e.Cancel = true;
• Occorre MinimizeBox = false
• Deve chiudersi non minimizzarsi
UI lenta
• Il disegno dei bit sullo schermo non e’
velocissimo 
• Per riempire i controlli con molti dati
• Visibile = False
• Ciclo
• Visible = True
• Usare BeginUpdate / EndUpdate se supportati
• Demo FillingComboVBRichClient
• (HighResolutionTimer)
Form Load
• Sempre Lento ! 
• Obiettivo
• Prima volta
• Ridurre il tempo di caricamento
• Successive volte
• Azzerare il tempo
Form Load first time (20% c.a.)
• VS.NET 2003
• Costruttore chiama InitializeComponent
• InitializeComponent
• Controlli Quadrati (Panel, Tab, Form)
• Sostituire con this.xxx.Bound = new Rectangle())
• Gerarchia
• Usare figlio.Parent al posto di Papà.Add
• E Top Down: prima il papà e poi il figlio
• Occhio che il Designer rigenera sempre tutto
• Agire subito prima del deploy
• Fare classe Finta che blocca il designer
• Tenere due form
• Su quella “Auto” fare modifiche e ricopiare il “Vera”
Form ReLoad 
• Form di dettaglio da aprire più volte
• Definire static il costruttore
• Che inizializza solo la prima volta la form
• Definire costruttore privato
• In pratica si tiene in memoria la form
• Meno costruzione/distruzione oggetti !
• Il GC non può scaricare la form se c’è bisogno
• Volendo si può precaricare da un background thread
• Al termine del Load della prima form
Collection di form
• Mettere le istanze dei form in collection
• Array – Collection Custom – etc...
• Si possono precaricare all’inizio in background
• Fra un attimo parliamo di thread
• Si possono caricare alla prima richiesta
• Occhio alla quantità di memoria occupata
• Se troppa il GC potrebbe scaricare il codice compilato
Form non-full screen
• FormBorderStyle = None
• Obbligatorio
• Altri valori fanno tornare il form full screen a runtime
• Ma ci perdiamo il bordo !!!
• Override del metodo Paint
• Disegnare noi il bordo
• Più semplice di quanto si creda
Forms Full-Screen & Controls
• Managed
• Text = “”
• Menu = null/Nothing
• …e se serve l’input panel o il menu?
• Native – SHFullScreen
• …e se l’utente usa l’help dell’input panel?
• Managed OnDeactivate()
• Native GetForegroundWindow
• Non dimentichiamoci uno shortcut 
• Per chiudere in caso di manutenzione (magari con password)
• Task List: come visualizzare una sola form
Scrollable Something
• System.Windows.Forms.ScrollableControl
è una finta
• Managed
• Panel come container dei child Controls
• Native
• ScrollWindowEx + SW_SCROLLCHILDREN
• E con la Second Edition
• … ancora peggio…
• Custom Control
• Il designer di VS 2003 non li supporta
• Nessun problema, lo inganniamo 
Display e Layout
Funzionalità dei
Device
• Orientamento
• Risoluzione
•
.NET Compact Framework 1.0 Service Pack 2 (oggi)
•
•
•
•
Gestione automatica delle form scrollabili
Evento Form.Resize
Gestione automatica dell’alta risoluzione
White paper su MSDN:
Developing Screen Orientation-Aware Applications
Display And Layout
.NET Compact Framework 2.0
•
Supporto all’orientamento
•
•
•
•
Docking e Anchoring
Proprietà AutoScroll – forms, panels
Metodi Suspend/Resume Layout
Metodo ChangeOrientation
•
•
Supporto alla risoluzione
Scaling automatico
•
Demo dopo con Fabio
SIP
• Display automatico su campo input
• Controllo da codice
• Aggiungere il controllo Software Input Panel
• SIP.Enabled = true/false
• Resize del form/controlli
•
•
•
•
Intercettare EnableChanged
Proprietà VisibleDesktop di tipo Rectagle
Height e Width per sapere la dimensione
Ctor per salvare la dimensione originale
Versione .NET CF Installata
• System.Environment.Version
• Major / Minor / Revision / Build
• N.B. I service Pack escono redistributable
• Non aggiornano . Cab sotto VS 2003
• Si devono copiare i cab sull’emulatore
• VS 2005 non è più così
• Connessione con ActiveSync dell’emulatore !
• Da Desktop
App.Path
• Magari
• OpenNETCF
• Reflection
• Assembly.GetExecutingAssembly().GetName().CodeBase
• System.IO
• Path.GetDirectoryName per strappare l’exe
Registry
• P/Invoke ?
• OpenNETCF
• Classe OpenNETCF.Win32.Registry
• SottoClassi Dedicate
•
•
•
•
ClassesRoot
CurrentUser
LocalMachine
Users
• CreateSubKey
• OpenSubKey
• DeleteSubkeyTree
File di Configurazione
<appSettings>
<add key=“nome” value=“xxxx” />
</appSettings>
• Da codice Namespace OpenNETCF.Configuration
• ConfigurtionSettings.AppSettings[“nome”]
• N.B. OpenNETCF 1.2
• Per applicazione Applicazione.exe.config
• Per DLL Applicazione.dll.config
• Solo per primo livello
• 1.3 Applicazione.exe.config
Threding in .NET CF
Semplice Intro
• Non usare il processore se non necessario
• Non usare polling !!!!
• Soprattutto per sincronizzare i thread
• Il multithread aggiunge complessità
• Per definizione un’applicazione multithread non
va più veloce...anzi
• Ma più sfruttare momenti di pausa
• Perché aspettare i dati da un DB invece di fare qualcos’altro nel
frattempo ?
• Perché non eseguire operazioni in background mentre l’utente
fa altro ?
Threading Namespace
•
.NET CF 1.0
•
•
•
•
•
Thread
CurrentThread
Priority
Sleep
Start
•
Foreground only !
•
.NET CF 2.0
•
•
•
•
•
•
•
•
•
Thread
CurrentThread
IsBackground
Name
Priority
Abort
Join
Sleep
Start
•
Fore e Back
Thread.Creazione
• .NET Compact Framework 1.0
• Creare e avviare thread è semplice
Thread myThread = new Thread(new ThreadStart(MyWorkerThread));
myThread.Start();
private void MyWorkerThread()
{
while (! workerThreadDone)
{
// simulate some processing
Thread.Sleep(1000);
}
}
Thread.Creazione
• .NET Compact Framework 2.0
• Creare e avviare thread è più semplice
Thread myThread = new Thread(MyWorkerThread);
myThread.Start();
private void MyWorkerThread()
{
while (! workerThreadDone)
{
// simulate some processing
Thread.Sleep(1000);
}
}
Demo Considerazioni
• Abbiamo tre problemi nelle demo precedenti
• Usiamo la variabile “i”
• Se facciamo partire due thread andiamo in scrittura
della stessa variabile
• Lo abbiamo fatto solo per Demo
• Se chiudiamo la App con il thread in corsa
• La Form sembra si chiuda...fra poco
• Se abbiamo bisogno di aspettare il thread prima
di fare altre operazioni
• Es Riempio Combo in parallelo ma prima di usarla il
thread deve aver finito
Application Shutdown
• 1.0 solo Foreground Thread
• L’applicazione termina solo quando tutti i thread
foreground finiscono
• Sembra che si chiuda ma i thread avviati proseguono
• Evitiamo la chiusura
• Oppure potremmo stoppare il thread
• Ma in 1.0 non c’è Abort
• Occorre usare una variabile - Polling ?!?!?!
• OpenNETCF.Threading
• ThreadEx
• MonitorEx, Semaphore, EventWaitHandle
2.0 Abort
• Possiamo chiedere a un thread .Abort
• Otteniamo un’eccezione ThreadAbortException
• Non facciamo Polling
• 2.0 anche Background Thread
• Terminati dal CLR se l’applicazione termina
• Thread.Abort chiamato dal CLR
• Per Default sono ForeGround
• IsBackGround = true;
Sapere quando ha finito
• 1.0 AutoResetEvent
• False prima di Start
• .Set() alla fine del lavoro del Thread
• .WaitOne()
• 2.0 Join
• Nessun AutoResetEvent da dichiarare
• Ne serve 1 per ogni thread (lavoro da fare)
• Nessuna variabile
Aggiornare UI da altri Thread
• Mai aggiornare i controlli direttamente
private void WorkerThread()
{
statusBar1.Text = “Sto facendo questo";
while (!workerThreadDone)
{
Thread.Sleep(1000);
}
}
1.0
• Nessun eccezione...pizza e basta 
• Control.Invoke
• Sincrono e senza parametri
private string statusBarText;
private void WorkerThread()
{
statusBarText = "WorkerThread active";
this.Invoke(new EventHandler(UpdateStatusBar));
while (!workerThreadDone)
{
Thread.Sleep(1000);
}
}
private void UpdateStatusBar(object sender, EventArgs e)
{
statusBar1.Text = statusBarText;
}
2.0
• .NET CF 1.0
•
•
Invoke (delegate)
• .NET CF 2.0
•
•
•
•
•
•
Invoke (delegate)
Invoke (delegate, object[])
BeginInvoke (delegate)
BeginInvoke (delegate, object[])
EndInvoke ()
NotSupportedException
N.B. 2.0
•
•
•
Eccezione se usato non correttamente
Asincrono
Parametri...non dobbiamo fare più variabili
2.0
private void WorkerThread()
{
statusBar1.Text = “Sto Facendo…calma";
while (!workerThreadDone)
{
Thread.Sleep(1000);
}
}
NotSupportedException
2.0
• Control.(Begin)Invoke
private delegate void UpdateSB (string statusBarEntry);
private void WorkerThread()
{
UpdateSB sbUpdater = UpdateStatusBar;
this.Invoke(sbUpdater, new object[] {"WorkerThread active"});
while (!workerThreadDone)
{
Thread.Sleep(1000);
}
}
private void UpdateStatusBar(string statusBarInfo)
{
statusBar1.Text = statusBarInfo;
}
Occhio alla chiusura !!!
• 1.0
• Foreground thread
• Dispose del Form uccide i controlli
• E il delegate fa la pizza
• 2.0
•
•
•
•
== 1.0
Background thread
Richiesto abort da CLR
Intercettare ThreadAbortException e fermare le invoke
• Potrebbe essere comunque troppo tardi
• Oppure evitare la chiusura come abbiamo visto
Non tutti sanno che …
•
•
•
•
•
•
•
•
Retargetable flag attribute
Typed DataSets
HTTP Server
Migrazione da eMbedded Visual Tools
Obfuscation
Compilazione da riga di comando
Control Design – RuntimeAssemblyAttribute
String.Intern()
Design guidelines di Microsoft
• Pocket PC 2003 SDK
• SmartPhone 2003 SDK
How To
• Custom TextBox
• managed o native ?
• Device ID
• KernelIoControl() - IOCTL_HAL_GET_DEVICEID
• Workaround
• Toolbar
• ImageList
• ListView con Second Edition e SP2
• DEMO #5
Fuori in 60 secondi
Creare una gestione dati in 60’’
DataSoul Framework
© 2004 Microsoft Corporation. All rights reserved.
This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.
Content created by 3 Leaf Solutions
Scarica

Slide 1 - Microsoft