Riempire due ComboBox da un DB - Rallentamento

martedì 12 aprile 2011 - 17.48
Tag Elenco Tags  VB.NET  |  .NET 2.0  |  Windows 7  |  Visual Studio 2008  |  MySQL 5.1  |  Office 2007  |  Internet explorer 8.0

paky50 Profilo | Newbie

Ciao a tutti,
dunque ho un form padre che apre un form figlio chiamato Inserimento.vb.
In quest' ultimo devo riempire collegandomi ad un DB apposito due ComboBox, uno relativo al comune di nascita ed uno relativo al comune di residenza.
Per far ciò utilizzo due fom_load con il seguente codice:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

non so bene per quale motivo (penso la doppia connessione al DB) per aprire il form figlio in questione occorrono circa 15 secondi, se commento una delle due form 5 secondi.
Esiste un modo per "alleggerire" il lavoro e impiegare meno tempo ad aprire la form?
Spero sia chiaro il problema.
Grazie.

kataklisma Profilo | Senior Member

>Ciao a tutti,

Ciao!

>dunque ho un form padre che apre un form figlio chiamato Inserimento.vb.
>In quest' ultimo devo riempire collegandomi ad un DB apposito
>due ComboBox, uno relativo al comune di nascita ed uno relativo
>al comune di residenza.
>Per far ciò utilizzo due fom_load con il seguente codice:

Scusami hai UN form Padre che apre UN form figlio....perchè utilizzi due gestori d'eventi Load?

Molto piu corretto è utilizzare l'evento Load per lanciare un Metodo contenente il codice di riempimento delle combobox....

>Private Sub Form2_Load(ByVal eventSender As System.Object, ByVal
>eventArgs As System.EventArgs) Handles MyBase.Load
> Timer1.Interval = 10000

Questo è un Timer che ha come Intervallo 10 secondi....sei sicuro che il problema non sia nel metodo implementato dal Timer?


------------------------------------------
Ignazio Catanzaro

http://blogs.dotnethell.it/swdev/

paky50 Profilo | Newbie

Grazie del consiglio, ho modificato il codice nel seguente modo:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Ma il tempo di attesa per aprire il FORM figlio è sempre di 12 secondi circa. Il tempo mi serve per mantenere aperta la porta di un device per un tempo determinato. Anche disabilitandolo il form tarda uguale ad aprirsi.

kataklisma Profilo | Senior Member

>Grazie del consiglio, ho modificato il codice nel seguente modo:

Di nulla :)

>Ma il tempo di attesa per aprire il FORM figlio è sempre di 12
>secondi circa. Il tempo mi serve per mantenere aperta la porta
>di un device per un tempo determinato. Anche disabilitandolo
>il form tarda uguale ad aprirsi.

Guarda utilizza una sola connessione, riempita la prima combobox non chiudere la connessione SQL ed effettua la seconda query .

Nel caso specifico sto notando che la query e quindi i risultati sono identici per entrambe le combobox, quindi, puoi utilizzare il seguente codice sfruttando una sola connessione ed una sola query :

Private Sub fillCombo() Dim ds As New DataSet Dim queryComuneR As String = " select * from db_comuni.comuni;" M.connessione.Open() M.adattatore = New MySqlDataAdapter(queryComuneR, connessione) M.adattatore.Fill(ds, "comune") 'DataSource Prima ComboBox ComboBoxComR.DataSource = ds.Tables("Comune") ComboBoxComR.DisplayMember = "comune" 'DataSource seconda ComboBox Me.ComboBoxComN.DataSource = ds1.Tables("Comune") Me.ComboBoxComN.DisplayMember = "comune" M.connessione.Close() End Sub
------------------------------------------
Ignazio Catanzaro

http://blogs.dotnethell.it/swdev/

paky50 Profilo | Newbie

Codice ulteriormente modificato nel seguente modo:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Ma anche in questo caso il tempo di attesa per aprire la form è di 6-7 sec. forse dovrei intervenire
su DB eliminando magari qualche Record inutile (tipo CodiceIstat che a me non serve) in modo da rendere più leggera la connessione...voi che ne pensate?
Grazie.

kataklisma Profilo | Senior Member

>Ma anche in questo caso il tempo di attesa per aprire la form
>è di 6-7 sec. forse dovrei intervenire
>su DB eliminando magari qualche Record inutile (tipo CodiceIstat
>che a me non serve) in modo da rendere più leggera la connessione...voi
>che ne pensate?

Intanto puoi notare che per il momento abbiamo dimezzato i tempi....concordo comunque che 6 secondi sono improponibili, dovresti tramite debug andare a vedere quale tra quelle istruzioni richiede più tempo andando ad individuare il collo di bottiglia....

Comunque sia non capisco perchè esegui la query due volte! Eseguila una sola volta ed impostala come datasource delle due combobox (ti ho fatto l'esempio nel mio ultimo post)!

Poi, altra cosa : su quale mole di dati stiamo lavorando?Il Database è in rete locale o è su un server esterno?Hai bisogno di inserire nel datasource della combobox TUTTI i record o è possibile trovare altre soluzioni?

------------------------------------------
Ignazio Catanzaro

http://blogs.dotnethell.it/swdev/

paky50 Profilo | Newbie

Codice così modificato:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

la doppia query era decisamente superflua. Grazie.
Nonostante ciò il tempo di attesa non varia.
In pratica ho un DB con un tabella comuni che contiene i campi:
Comune Provincia CAP Prefisso_tel Codice_istat Codice_Catastale Sito_comune
potrei intervenire sul DB ed eliminare gli ultimi 3 campi che a me non servono però prima di far ciò volevo provare ad ottimizzare ancora il codice.

P.s.: ho provato a commentare la chiamata al metodo fillCombo è l'apertura è istantanea.

kataklisma Profilo | Senior Member

Prova cosi :

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
------------------------------------------
Ignazio Catanzaro

http://blogs.dotnethell.it/swdev/

paky50 Profilo | Newbie

Avevo già provato ma utilizzando un uncio dataset quando cambio valore nel ComboBoxR lo cambio automaticamente nel comboBoxN e viceversa.
Per cui ho dichiarato il secondo dataset.

kataklisma Profilo | Senior Member

>Avevo già provato ma utilizzando un uncio dataset quando cambio
>valore nel ComboBoxR lo cambio automaticamente nel comboBoxN
>e viceversa.
>Per cui ho dichiarato il secondo dataset.

Ma nel sorgente non vedo nessun DataBinding....ne tanto meno i valori nel dataset vengono modificati....quindi perchè istanziare due dataset?

Hai apportato la modifica alla query ? "Select comuni from Comuni" al posto di "Select * from Comuni" cosi intanto ottimizzi la chiamata al DB.

------------------------------------------
Ignazio Catanzaro

http://blogs.dotnethell.it/swdev/

paky50 Profilo | Newbie

Se non istanzio due dataset distinti nel momento in cui cambio valore al primo ComboBox si cambia il valore anche nell'altro ComboBox e viceversa.

jackk87 Profilo | Junior Member

Ciao ho affrontato il tuo problema un pò di tempo fa e non sono riuscito a scendere sotto i 5 secondi in quanto un db che contiene tutti i comuni d'italia sta sui 9000 record e riempire una combobox di 9000 elementi 5 secondi sono anche pochi
per farla breve al posto della combobox ho inserito una texbox che quando l'utente inserisce le iniziali del comune che gli interessando preme invio e gli esce la lista dei comuni che iniziano con quelle lettere in modo da passare a una query di circa 12-13 volte meno quella iniziale. Per esempio se devo cercare campobasso e nella textbox inserisco camp poi premo invio ed escono tutti i comuni che iniziano per camp.
Spero di esserti sstato di aiuto e di aver capito il tuo problema

paky50 Profilo | Newbie

Stavo pensando a questa soluzione oggi pomeriggio ma non avrei ancora idea su come implementare il codice...

kataklisma Profilo | Senior Member

>Ciao ho affrontato il tuo problema un pò di tempo fa e non sono
>riuscito a scendere sotto i 5 secondi in quanto un db che contiene
>tutti i comuni d'italia sta sui 9000 record e riempire una combobox
>di 9000 elementi 5 secondi sono anche pochi

Ragazzi in questi caso pronuncio sempre un'aneddoto molto divertente che dovrebbe far pensare :

"Con un processore avente potenza equivalente agli attuali processori di un quasiasi telefono non smartphone dei giorni nostri, gli americani nel '69 hanno mandato l'uomo sulla Luna"

Come dicevo prima, c'è un collo di bottiglia non indifferente : ho appena simulato un dataset di 10000 record (effettuati con un ciclo e non con un query) e la visualizzazione dei dati nella combobox si ha in meno di un decimo di secondo (processore i7 920).

Quindi, se si effettua una query mirata al solo campo "comune" e si utilizza la property DataSource il tutto fila per il meglio salvo bottlenek sparsi....

La "Ricerca Incrementale" è di facile implementazione : puoi precaricarti il dataset per intero, trasformarlo in una Lista generica e tramite il metodo "Where" effettuare il filtro oppure puoi lanciare una query ogni qual volta viene richiamato l'evento TextChanged della TextBox.

Comunque sia prova a fare questo Test in un nuovo progetto :

private void button1_Click(object sender, EventArgs e) { DateTime Test_Inizio = DateTime.Now; DataSet d = new DataSet(); d.Tables.Add("Prova"); d.Tables[0].Columns.Add("Comuni", typeof(string)); for (int i = 0; i < 10000; i++) d.Tables[0].Rows.Add("Prova" + i.ToString()); List<string> ComuniList = CreaListaComuni(d.Tables[0]); comboBox1.DataSource = ComuniList; comboBox1.DisplayMember = "Value"; MessageBox.Show((Test_Inizio - DateTime.Now).ToString()); } private List<String> CreaListaComuni(DataTable dtData) { List<string> str = new List<string>(); foreach (DataRow row in dtData.Rows) { foreach (DataColumn Col in dtData.Columns) { str.Add(row[Col].ToString()); } } return str; }

P.S Cosa importantissima: se stai effettuando i test da Visual Studio ed hai attiva la modalità Debug, sbagli! Compila la soluzione in modalità release ed apri l'exe generato.
------------------------------------------
Ignazio Catanzaro

http://blogs.dotnethell.it/swdev/

paky50 Profilo | Newbie

Se modifico la query come dici tu non riesco a recuperare i campi della stessa tabella come per esempio CAP e PROVINCIA.
Al max la posso modificare cosi:

select comune,provincia,cap,prefisso_tel from db_comuni.comuni;

ma non cambia nulla a livello di tempi di attesa.

paky50 Profilo | Newbie

Quest'esempio è in VB.NET? :D

kataklisma Profilo | Senior Member

>Quest'esempio è in VB.NET? :D

Scusami! Eccolo in VB.Net

Private Sub button1_Click(sender As Object, e As EventArgs) Dim Test_Inizio As DateTime = DateTime.Now Dim d As New DataSet() d.Tables.Add("Prova") d.Tables(0).Columns.Add("Comuni", GetType(String)) For i As Integer = 0 To 9999 d.Tables(0).Rows.Add("Prova" & i.ToString()) Next Dim ComuniList As List(Of String) = CreaListaComuni(d.Tables(0)) comboBox1.DataSource = ComuniList comboBox1.DisplayMember = "Value" MsgBox.Show((Test_Inizio - DateTime.Now).ToString()) End Sub Private Function CreaListaComuni(dtData As DataTable) As List(Of [String]) Dim str As New List(Of String)() For Each row As DataRow In dtData.Rows For Each Col As DataColumn In dtData.Columns str.Add(row(Col).ToString()) Next Next Return str End Function

Non l'ho testato ma non dovrebbero esserci problemi ;)
------------------------------------------
Ignazio Catanzaro

http://blogs.dotnethell.it/swdev/

paky50 Profilo | Newbie

Il codice va bene ( a parte l'inversione dei termini della differenza tra i tempi ).
Tuttavia a questo punto l'unica soluzione possibile credo che resti quella della della ricerca incrementale.
Avendo iniziato VB.NET da un mesetto però ho qualche problema.
Il primo passo da come ho capito è quello di associare un dataset ad una lista generica.
Devo aprire un altro thread?
Grazie.

paky50 Profilo | Newbie


>La "Ricerca Incrementale" è di facile implementazione : puoi
>precaricarti il dataset per intero, trasformarlo in una Lista
>generica e tramite il metodo "Where" effettuare il filtro oppure
>puoi lanciare una query ogni qual volta viene richiamato l'evento
>TextChanged della TextBox.

Se lancio una query quando richiamo l'evento TextChanged come faccio a visualizzare il risultato nella text.box stessa??? E' un sorta di ricorsione?

Grazie
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5