aprile 2007 - Posts
Oggi, al MIX (non sono al MIX, ma ho incontrato alcuni amici..la conferenza è nello stesso minuscolo :-) albergo dove sono io) hanno rilasciato Silverligth.
Fra due ore parto per la MEDC 2007 di Las Vegas. Spero di trovare il tempo (la nostra DevCon 2007 è alle porte) di postare qualche novità su .NET CF 3.5, LINQ, WCF, sul Device Emulator 3.0 e soprattutto sul mercato americano che sicuramente è più avanti del nostro.
Abbiamo definito anche la seconda Bonus Session: era già stata pubblicata nell'agenda fin dall'inizio e abbiamo deciso di tenerla in questo slot.
Grazie ai vostri feedback sulla sessione VSTS abbiamo preso un'altra decisione importante:
1) La sessione su VSTS sarà di taglio introduttivo ma con esempi basati su EstatesManagement 3.0, la nostra applicazione di esempio di cui abbiamo già parlato in questo blog. In pratica vedremo come funzionano i vari strumenti posizionandoli nel modo corretto rispetto ad una applicazione.
2) Abbiamo introdotto una nuova sessione: PRE13 per rispondere ad alcuni quesiti che normalmente ci vegono fatti nei nostri corsi o consulenze architetturali; in allegato il dettaglio della nuova sessione.
L'introduzione del nuovo ha scatenato una serie di modifiche in cascata agli slot dell'agenda: non sono cambiate le altre sessioni, ma per cercare di trovare il miglior posizionamento possibile e evitare sopvarapposizioni di argomenti fra le due sale abbiamo dovuto spostare alcuni slot da una sala all'altra in diversi orari; le modifiche di timing riguardano solo il secondo giorno. L'agenda è disponibile sempre sotto http://devcon.devleap.com/agenda.aspx
PRE13
Implementing .NET distributed applications for everyday solutions (for the “Gestionale”)
16/05/2007 - 12:15-13:30
Speaker: Roberto Brunetti & Paolo Pialorsi
Descrizione: A DevCon 2005 abbiamo presentato un’idea di architettura di un’applicazione .NET 2.0 (Estates Management) basata su entità di business che “viaggiano” fra i numerosi layer applicativi.
La nuova versione della nostra applicazione è composta da 70 progetti che utilizzano Windows Workflow Foundation e Windows Communication Foundation arrivati con .NET 3.0.
Sono due i problemi da affrontare su un modello applicativo così articolato:
1) Implemetare il codice dei vari layer per ogni entità di business per le operazioni più comuni: scrivere questo codice, simile per ogni entità, è un’operazione lunga e costosa
2) I modelli applicativi basati su entità vengono percepiti erroneamente come “bloccati e chiusi”.
In questa sessione vedremo dapprima Guidance Automation Toolkit e Guidance Automation Extension per l’implementazione del modello applicativo e la generazione di codice con un esempio che produce alcune dei layer di Estates Management per poi rendere elastico (nel senso di estendibilità) il modello basato su entità.
Le applicazioni reali che scriviamo per i nostri clienti si basano su questo modello applicativo, anche se, chiaramente abbiamo poi centralizzato tutta una serie di funzionalità in un framework applicativo che referenziamo in ogni progetto.
Argomenti trattati:
- Architetture applicative
- GAX-GAT
- Modellazione di entità
Abbiamo appena pubblicato la scheda del nostro nuovo corso ufficiale LINQ Intro.
Gli argomenti ricalcano i capitoli del nuovo libro che Marco e Paolo hanno redatto per Microsoft Press. A brevissimo sarà disponibile in lingua inglese (per adesso è prenotabile su Amazon: http://www.amazon.com/gp/product/0735623910/?tag=se04-20).
Vi comunico anche l'apertura di www.introducinglinq.com, il sito ufficiale del libro con blog e forum.
Ho ricevuto diverse mail sul primo episodio con richieste di chiarimenti, soprattutto per il punto apertura connessioni; ho pensato di fare velocemente un secondo episodio sul tema:
Questo è quanto ho scritto a riguardo:
Fare poche Open/Close al DB - Con SQLCE il costo di apertura e chiusura di una connessione è alto
- Non esiste Connection Pooling per SQLCE
- Conviene quindi lasciare aperta la connessione al DB se si cercano le prestazioni
- Tenere quindi le connessioni statiche (con un singleton magari) nel Dal Layer
- E' anche vero che se le connessioni devono essere più di una (lavoriamo in multithread eseguendo operazioni in parallelo) diventa più complicata la loro gestione (e chiusura).
- Spesso, se non sono alla canna del gas, apro e chiudo le connessioni ogni volta
- Avendo un generatore di codice diventa semplice modificare questo comporamento
- Le connessioni comunque pesano quindi in applicazioni multi-thread pesare bene queste considerazioni
Come indicavo nell'ultimo punto, è importante pesare bene queste considerazioni; le performance sono importanti ed è importante cercare di massimizzarle nei punti critici dell'applicazione; è altrettanto importante la manutenibilità del codice e la valutazione delle controindicazioni.
Tenere aperte le connessioni significa migliorare le performance ma
- Spesso, in una applicazione, le operazioni che usano i dati fanno parte di un processo più ampio che parte con una azione da parte dell'utente; le performance percepite dall'utente in questo caso sono la cosa più imporante.
- Se riempiamo una griglia con 20 record paginati da una tabella con migliaia di record sicuramente il tempo di refresh della UI e il recupero delle informazioni (l'esecuzione della query) sono superiore all'apertura e chiusura della connessione
- Se l'operazione sui dati non è immediata (oltre 1 secondo per capirci) il tempo di apertura e chiusura è abbastanza ininfluente
- Normalmente i database SDF stanno su una memory card (Compact Flash o SD che sia) e spesso il palmare va in stand-by (GIUSTAMENTE) durante l'utilizzo: la filosofia su Windows CE consiste proprio nel sospendere e ripartire dall'esatto punto in cui si è lasciato il device questo vale per Pocket Outlook così come per le nostre applicazioni
- Se non usiamo il device, probabilmente il Power Save stacca la scheda SD per risparmiare batteria. Se abbiamo una connessione aperta è molto probabile che venga persa e l'applicazione non sia utilizzabile se non riaprendo la connessione
- Ancora peggio è utilizzare un SqlCeResultSet in binding su un controllo della user interface: in questo caso la connessione si perde durante lo stand-by o lo spegnimento della shceda...con un errore non proprio carino per l'utente...rivedere il primo episodio per altri problemi (prestazioni comprese) di un SqlCeResultSet
- Una connessione sempre aperta porta anche a "problemi" di organizzazione: ad esempio occorre chiuderla prima di una operazione di Compact, Repair, Verify
- In generale, come dicevo nel primo episodio, è vero che dal punto di vista delle performance pure converrebbe tenere sempre aperta una connessione, ma è altrettanto vero che i contro non sono pochi. Tutti "i contro" possono essere risolti da codice, ma, come dicevo, in generale, se non sono alla canna del gas :-) uso un mio Helper (una versione è disponibile sotto http://thinkmobile.it/files nella demo Sql 2005 Mobile Performance) che apre e chiude le connessioni.
- L'unica eccezione che uso per i comandi complessi è l'utilizzo di un comando Prepared (un esempio è sempre nella demo indicata in cui sono presente anche i tempi di accesso di tutti i metodi di accesso ai dati per una comparazione). In questo caso viene passato all'helper un parametro per non distruggere la connessione (in pratica non viene indicato il CommandBehavior.CloseConnection su DataReader) e una variabile statica per tenere vivo il comando preparato
- Ancora su SqlCeResultSet
- spesso una maschera che presenta una griglia apre una seconda maschera di dettaglio (una seconda griglia con il dettaglio ordini ad esempio o una maschera di editing della prima): con un resultset statico o key-driven ci sono dei lock sui record...cosa che nessuno di noi vuole avere durante un'update o peggio ancora una Delete del record dalla maschera secondaria
- Se facciamo operazioni in background, come ad esempio una Merge Replication, che succede alla nostra griglia (o ai campi in bind sulla user interface) mentre vengono aggiornati i dati dietro le quinte ? Vero che potremmo usare un ResultSet non aggiornabile e non-sensitive (Insensitive per l'enum)...ma in questo caso perchè non usare un DataReader ?
- Il punto 2 precedente è opinabile perchè un DataReader non consente binding...vero...però è altrettanto vero che non dovremmo mai portare oggetti "database" (classi di accesso ai dati) sulla User Interface...altrimenti ci leghiamo all'implementazione specifica del DB e non possiamo cambiare database (e metodi di accesso ai dati nelle tecnologie a venire) se non sbaraccando tutto
- Sempre a proposito di connessioni potrebbe essere sensato avere due connection string in una applicazione: una per leggere i dati (Mode=Read Only) e una tradizionale per letture/scritture: in questo modo possiamo evitare SLock inutili. Se usiamo Mode=Read Only occorre impostare una path per il TempDB tramite l'attributo Temp File Path.
- A proposito di TempDB occhio che se crasha SQLCE il tempdb resta nella posizione: occorre cancellarlo da codice. Il TempDB viene usato anche per tutte le query che non possono sfruttare un indice....ma non ce ne dovrebbero essere...
Girando per varie aziende per consulenze e progettazione di architetture mi trovo spesso ad affrontare problematiche di performance o problemi sugli applicativi esistenti.
Nelle varie sessioni alle conferenze che ho tenuto (dalla Windows Professional Conference 1998, in cui ho tenuto la prima sessione in Italia su SQLCE 1.0...ve lo ricordate il primo serio mini-db per Windows CE, alla DevLeap Conference 2007 e SQL Conference 2007) ho sempre cercato di sottilineare quanto sia importante evitare di utilizzare automatismi se non per fare prove o applicazioni molto "ristrette" sul numero di dati e funzionalità. Inevitabilmente ogni automatismo ha delle controindicazioni quindi occorre valutarne sermpre l'utilizzo.
Dopo 10 anni di mobility ho pensato di buttare giù una serie di "cose da evitare" per avere un'applicazione più semplice da manutenere, più performante e con meno casini (casini è la parola giusta) di gestione. Ovviamente ognuno è libero di fare come vuole e libero di ribattere qualunque punto, anche perchè esistono applicazioni che lavorano su 50 record al massimo e quindi forse non necessitano dell'attenzione necessaria ad applicazioni più complesse. E' altrettanto vero però che le piccole applicazioni crescono nel tempo e spesso un problema si porta dietro altri problemi.
L'esperienza di sviluppo web ha portato anche le tradizionali applicazioni client-server a lavorare con i dati in modo disconnesso con notevoli miglioramenti sui lock, sulle possibilità di eseguire elaborazioni in background (ad esempio una replica dei dati mentre l'utente lavora) e così via.
Ecco una prima lista di cose da evitare non in ordine di importanza: quando trovo 10 minuti liberi continuo la lista in vari episodi. Il tutto fa riferimento a SQLCE 2.0/3.0/3.1 e .NET CF 2.0: le ultime versioni disponibili al momento della scrittura di questo post.
- Non usare MAI DataSet
- sono oggetti pesanti e farraginosi
- sono inutili in una soluzione disconnessa: le letture si fanno con il DataReader e le scritture con query di update/insert/delete
- Non usare SqlCeResultSet
- le performance non sono quelle promesse
- Se usate Key-Driven o Static incorrete in lock e casini se poi volete eseguire operazioni in background
- Lavorare sempre disconnessi dai dati
- Non fate lock se non quando espressamente necessario alla logica applicativa
- E' possibile fare operazioni sui dati in background
- Usare Base Table Cursor se servono dati da una sola tabella
- La Seek di un record su un indice ha tempi notevolmente inferiori di una SELECT
- Un Range al posto di una WHERE ha tempi di accesso mostruosamente inferiori
- Per questi primi punti, se volete farvi un'idea tei tempi di accesso di cui parlo date un occhio all'applicazione gratuita che ho scritto per una conferenza e che testimonia la differenze fra DataSet, ResultSet, Reader, BTC: http://thinkmobile.it/files/folders/mmdcii/entry5239.aspx. Se non avete voglia di riprovare tutti gli esempi lo zip contiene un foglio di Excel con i dati che ho raccolto eseguendo 10 volte ogni test e indicando i valori singoli e la media
- Gli oggetti come DataSet pesano sulla memoria complessiva
- Quando interviene il Garbage Collector, se non si possono eliminare oggetti in memoria (ad esempio il dataset è attivo e bindato ad una griglia), vengono eliminati dalla cache i metodi compilati...che dovranno essere poi ricompilati alla successiva esecuzione rallentandone l'esecuzione
- Fare poche Open/Close al DB
- Con SQLCE il costo di apertura e chiusura di una connessione è alto
- Non esiste Connection Pooling per SQLCE
- Conviene quindi lasciare aperta la connessione al DB se si cercano le prestazioni
- Tenere quindi le connessioni statiche (con un singleton magari) nel Dal Layer
- E' anche vero che se le connessioni devono essere più di una (lavoriamo in multithread eseguendo operazioni in parallelo) diventa più complicata la loro gestione (e chiusura).
- Spesso, se non sono alla canna del gas, apro e chiudo le connessioni ogni volta
- Avendo un generatore di codice diventa semplice modificare questo comporamento
- Le connessioni comunque pesano quindi in applicazioni multi-thread pesare bene queste considerazioni
- Merge Replication asincrona
- Ha senso per non bloccare la User Interface
- Ha senso per poter continuare a lavorare mentre la replica è in corso
- Per questo dicevo di non usare lock e strumenti di accesso ai dati (come i ResultSet) che potrebbero portarsi dietro dei lock.
- Con lock attivi alcune operazioni di Merge non si possono fare e comunque vengono rallentate moltissimo
- Usate un Agent Profile tarato per le connessioni che utilizziamo
- Gli Agent Profile di default prevedono alcune casistiche, ma se cercate le performance durante la replica (e i costi del GRPS/UMTS) ha senso personalizzarli
- Usare, se lo scenario lo consente, Filtri orizzontali e verticali per minimizzare il traffico dei dati e le operazioni da effettuare server-side
- Non usare nei filtri clausole WHERE che mimino i JOIN: usare Join filter
- Usare il più possibile precomputed partition
- Non concatenare MAI le stringhe, usate lo StringBuilder che evita la creazione di oggetti inutili
- Soprattutto non farlo nei cicli !
- Non fate Add Web Reference dai progetti di user interface
- Usate un factory pluggabile
- Le tecnologie cambiano (in .NET CF 3.5 arriva WCF): è importante poter cambiare il Factory visto che protocolli e tecnologie cambiano nel tempo
Torno ad un progetto, ci sentiamo presto
Mi sono imbattuto in questo bug...e purtroppo non sono riuscito a capire da cosa deriva visto che in un altro Guidance Automation Package funziona con (almeno mi sembra) stesse impostazioni.
Il file TypeAlias.xml serve per dare un nome logico, facilmente referenziabile, ad un assembly. Contiene per default
<?
xml version="1.0" encoding="utf-8" ?>
<
Types xmlns="http://schemas.microsoft.com/pag/gax-core">
<
TypeAlias Name="Evaluator" Type="Microsoft.Practices.RecipeFramework.Library.ValueProviders.ExpressionEvaluatorValueProvider,Microsoft.Practices.RecipeFramework.Library" />
</
Types>
purtroppo l'evaluator sembra dare problemi e non viene "rintracciato" a runtime.
Inserendo il Type completo (preso da questo post o direttamente dal file) e inserito nella definizione dei metadati del package funziona !
Hope useful
Già nella CTP precedente era stato aggiunto un comando comodissimo per la resitrazione di un Guidance Automation Package durante lo sviluppo, ma...purtroppo (visto il tempo che ho perso) me lo ero perso.
Sperando di risparmiarvi un po' di tempo (anche se il peppino sono stato io a non accorgemene): se non aggiungete nuove Recipe, template o modificato la sezione HostData (che serve per l'integrazione con VS 2005) si può fare Quick Register da tasto destro sul progetto GAT....ci mette 2 secondi invece di 1 minuto.
In pratica salta tutto il processo di riregistrazione.
Hope useful
A DevCon 2007 abbiamo due slot dedicati a Visual Studio Team System: l’idea originale della sessione è quella di mostrare il prodotto su un’applicazione che i partecipanti alle precedenti edizioni conoscono e che si è arricchita rispetto all’edizione 2005 di
1) Accesso asincrono al BIZ e DAL
2) Utilizzo efficiente del Broker di SQL Server
3) Interfaccia Windows Presentation Foundation che sfrutta il BIZ Layer presente
4) Windows Communication Foundation per la gestione delle comunicazioni
5) Windows Workflow Foundation
6) Merge Replication integrata per Smart Client
Il risultato sono 65 progetti Visual Studio che faranno compagnia ai partecipanti in varie sessioni della conferenza e che segue il nostro modello di sviluppo delle applicazioni reali che sviluppiamo per i nostri clienti. Alcune informazioni più dettagliate sono disponibili quì
Alcuni partecipanti mi hanno scritto direttamente chiedendo il livello della sessione in conseguenza del fatto che non utilizzano ancora Team System. Da qui la domanda estesa a tutti i partecipanti: quanti di voi utilizzano Team System ? Se nessuno dei partecipanti lo utilizza realmente ha senso scendere un attimo con il livello e fare una introduzione a tutti gli strumenti della suite vedendoli sul progetto reale, senza dare per scontato niente.
Come sapete vogliamo confezionare una conferenza da cui possiamo avere il maggior ritorno in termini di investimento:
· è inutile sparare in alto su un argomento che ancora in Italia non ha preso piede
· è più efficace introdurre tutti gli strumenti
· Vorremmo comunque evitare il classico esempio Hello World (un client WinForm che chiama un WS) che resta fine a se stesso, presentando il tutto comunque applicato ad una applicazione composta da 65 progetti in modo da dare subito una collocazione corretta agli strumenti
- Quanti dei partecipanti a DevCon sono venuti a settembre al VSTS Day organizzato da noi a Segrate ? In quell'occasione abbiamo visto una introduzione agli strumenti su un fac-simile di una applicazione con una decina di progetti.
Facci sapere direttamente il tuo parere, rispetto ai quesiti posti, scrivendo direttamente a roberto@devleap.it
Hope useful per tutti i partecipanti.
Oggi mentre stavo creando un controllo AJAX custom per una applicazione mi sono imbattuto in questa "perla" :-)
Uno dei sistemi per implementare un controllo custom è implementare l'interfaccia IScriptControl (System.Web.UI). L'implementazione richiede due metodi:
protected virtual System.Collections.Generic.IEnumerable<ScriptDescriptor> GetScriptDescriptors()
protected virtual System.Collections.Generic.IEnumerable<ScriptReference> GetScriptReferences()
Terminato e debuggato il controllo prima di rilasciarlo l'ho passato sotto Code Analysis di VSTS (ex FxCop) e ho ottenuto queste due errori di Design del mio controllo:
Warning 4 CA1024 : Microsoft.Design : Change 'GetScriptDescriptors' to a property if appropriate. C:\Applications\EstatesManagement\Current\DevLeap.Library.Web.UI.AjaxControls\TextBoxWithWSValidation.cs 58 DevLeap.Library.Web.UI.AjaxControls
Mi piacerebbe trasformare il tutto in proprietà, peccato che siano metodi dettati da una interfaccia del framework :-)
Non è la prima volta che mi capita di ottenere errori sul codice del FW stesso, ma avendo a disposizione una connessione ad internet ho pensato di condividere questa simpatica esperienza :-)
D'altra parte c'è pure scritto: Change xxx to a property if appropriate quindi in realtà le mani avanti le hanno messe :-)
La storia comunque sarebbe più lunga per l'implementazione esplicita o implicita dell'interfaccia...
Ecco il risultato delle giornate fatte con Paolo per l'aggiornamento alla versione 3.0 della nostra famosa applicazione Demo che accompagna i nostri corsi e che accompagnerà molte sessioni della DevCon 2007.
Ho pubblicato il diagramma visibile in parte in questo blog e completo sotto http://thinkmobile.it/photos/application_diagram/images/6074/original.aspx.
Il diagramma è in versione Beta2 e non comprende tutti i progetti della solution (sono 65 ad oggi...ma i lavori stanno continuando): questa parte è relativa a
- Servizi WCF
- Servizi ASMX
- Windows Workflow Foundation (non comprende il drill-down dei singoli progetti)
- Client Windows Form diretto sul BizLayer
- Client Windows Form via ServiceAgent pluggabile verso i servizi WCF
- BizLayer
- DalLayer
- MSMQLayer
- Service Broker
- Servizio Windows per "scodare messaggi in coda"
- Applicazione Windows Form per "scodare messaggi in coda"
- Sito Web tradizionale, sito web basato su AJAX e sito Web mobile
Ho escluso per adesso la parte (20 progetti c.a.) mobile.
Maggiori dettagli sulle varie componenti a breve.
Il diagramma nel post verrà tagliato a causa del layout. La versione completa è su http://thinkmobile.it/photos/application_diagram/images/6074/original.aspx (occorre fare un po' di zoom dal browser)

Articolo da me pubblicato su week.it del 6/3/2007
Mesi caldi per lo sviluppatore mobile. Fra pochi giorni dovrebbe uscire una prima versione del Windows Mobile 6.0 Sdk, a maggio è previsto il rilascio di Windows Embedded Ce 6.0, mentre il 12 febbraio è stato rilasciato un altro componente della famiglia destinato a chi sviluppa sui minuscoli dispositivi embedded basati su Arm7/Arm9, con o senza Mmu, che da tempo conosciamo con il nome di Spot.
Il framework richiede pochi Kilobyte di Ram (256Kb il minimo richiesto) e un processore “ridicolo” in confronto anche ai dispositivi Windows Ce. Il framework è affiancato da un Sdk che s’installa su Visual Studio 2005 per estendere lo sviluppo di applicazioni C# (per ora Vb.Net non è compreso) anche al mondo Spot. Le librerie a disposizione sono in versione 2.0 e comprendono la classica mscorlib, la System.dll e una serie di liberie Microsoft.Spot che s’installano sotto x:\Program Files\Microsoft .NET Micro Framework\v2.03036\Assemblies. Le librerie comprendono Graphics, Hardware, Native, Net e TinyCore (Tiny Clr era il nome precedente del Micro Framework).
Si possono scrivere device driver direttamente in C# utilizzando le interfacce standard SPI, I2C, GPIO e USART. Interessante è l’estendibilità degli emulatori che consentono di testare e debuggare il codice senza device reali aggiungendo, per esempio, periferiche simulate (sensori o “servi” per esempio).
L’Sdk comprende una serie di sample e un help che, come ormai accade per quasi tutti i prodotti, s’integra con la documentazione di Visual Studio. Ultima nota: il sistema embedded Micro Framework non è real-time.
Altre info
- Un esempio di codice per il classico Hello World usando le librerie Microsoft.Spot è visibile all’indirizzo:
http://blogs.devleap.com/rob/archive/2007/02/22/net-micro-framework-2-0.aspx
Semplice .bat per automatizzare il processo di creazione di un .chm / .hxc. Ci sono altri tool, ma non sono ancora allineati alla versione di Marzo.
Il normale processo richiede 13 step abbastanza pesanti: questo bat automatizza il tutto.
Necessita di SandCastle March CTP e HTML Help Workshop (richiesto da SandCastle e non dal .bat)
Potete commentare/scommentare l'ultima riga per la creazione del file .hxc. Il file .chm viene sempre generato.
Si utilizza dopo aver abilitato i commenti da VS 2005 (o da compilatore a riga di comando) per un assembly singolo.
Copiate il file nella directory dove avete installato SandCastle nella sottodirectory Examples\Sandcastle (C:\Program Files\Sandcastle\Examples\Sandcastle ad esempio): sovrascrivete il file esistente che contiene un errore e non è parametrizzato sugli assembly di cui generare il tutto; l'originale lavora su test.dll cablato nel .bat.
La sintassi è la seguente:
build_Sandcastle.bat [vs2005|notVS] FilePath(without dll/exe) OutputFileName.
Il primo parametro indica se l'assembly è stato compilato da Visual Studio oppure da riga di comando.
Il secono parametro rappresenta il nome dell'assembly (SENZA .dll o .exe !!!!) e l'ultimo parametro il nome del file .chm/.hxc da generare con l'help.
Trovate lo zip (con dentro il bat) sotto: http://devlab.devleap.it/Files/Utility/build_Sandcastle.zip
Spero utile
Non riuscivo più ad aprire un Data Generation Plan di VSTS for DB Pro. Mi dava il seguente errore "Failed to Load .dgen Failed to deserialize this file. There is an error in XML document. Fix the error manually editing the .dgen file and then reloading the file".
L'errore nel file .dgen non c'era, soprattutto non capivo perchè era uscito questo errore visto che non lo avevo cambiato da giorni, ma a scanso di equivoci l'ho recuperato in versione precedente da TFS...non si è risolto niente....
Dopo 20 minuti ho capito che se tengo aperto il designer di un form di un progetto mobile il designer di .dgen si impalla e non riesce ad aprire nessun file.
Se capitasse anche a voi è sufficiente chiudere il designer di form mobile e aprire il .dgen: sembra, in pratica che il designer di WinForm Mobile dia fastidio al Data Generation Plan Designer.
More Posts
Next page »