Visualizzazione progressbar durante connessione al db

martedì 17 aprile 2007 - 11.49

trinity Profilo | Guru

salve ragazzi,
io vorrei in vb net 2005 che mentre il mio applicativo si connetto ad un db sql server, la progressbar venisse visualizzata.

tenete presente che la progressbar deve essere solamente un oggetto che appare per intrattenere l'utente mentre il software connette al db pertanto la proprietà style della progressbar l'ho impostata su Marquee.

solo che se faccio la connessione la progressbar resta immobile all'inzio mentre avviene la connessione al db.

Come posso fare?

io ecco come scrivo il codice:

Imports System.Data.SqlClient
Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click
'==========AVVIO LA CONNESSIONE AL DATABASE==========
Dim Db As New SqlConnection
Me.ProgressBarl1.Visible = True
Application.DoEvents()
Try
Db.ConnectionString = " Data Source=apollo;Initial Catalog=c59onlinefr;Integrated Security=SSPI;"
Db.Open()
Catch
MessageBox.Show("Attenzione impossibile collegarsi al database dell'Apt di Frosinone", "C59.Net", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
Application.DoEvents()
Me.Panel1.Visible = False
End Sub
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

denis.basei Profilo | Senior Member

Ciao Fabio,

ho scoperto da poco una tecnica interessante per mantenere "viva" l'interfaccia operatore mentre vengono fatte delle operazioni che impegnano abbastanza il processore: controllo backgroundworker. Ti rimando a questo link dove puoi trovare spiegazioni ed esempi www.dotnet2themax.it/ShowContent.aspx?ID=873ee1ec-2b1f-45fc-9707-1a75e48224d9.

Ciao

Denis

gigi90 Profilo | Senior Member

Gia come dice giustamente denis.basei per non tenere bloccata l'interfaccia utente(durante operazioni che richiedono tempo come le interrogazioni ai database) e per non dare all'utente quel senso di "applicazione bloccata" potresti usare il Threading di .Net affidandoti al controllo Backgroundworker oppure alle varie classi definite nel namespace System.Thread.
Per poter utilizzare una progressbar per visualizzare il progresso, devi implementare del codice a seconda dei casi e delle operazioni che fai sul database per poter incrementare lo stato.
Spiegavi esattamente cosa vuoi fare, così vediamo insieme di scegliere le soluzione più coerente al tuo caso.

trinity Profilo | Guru

allora io voglio fare questo:

mentre la form effettua la connessione al database ossia una open, durante questa fase deve apparire la progressbar che intrattiene l'utente e dopo che la connessione è avvenuta la progress deve scomparire.
Per questo motivo ho scelto come style della progress il tipo marquee.
Solo che se eseguo il seguente codice:

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

la progressbar non si muove durante la connessione al db. ecco il problema che devo risolvere



Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

denis.basei Profilo | Senior Member

Riflettendo sul tuo problema forse la progress bar non è la miglior cosa. Una progress bar per sua natura deve mostrare all'operatore l'avanzamento "più o meno reale" delle operazioni. Dato che non sei in grado di sapere a priori quanto durerà l'operazione di connessione al database e quindi di formulare una regola che leghi ProgressBar.Value con la percentuale di avanzamento della connessione non sarebbe preferibile mostrare all'operatore in una label il messaggio "Connessione in corso" ed a connessione avvenuta azzerare la label?

gigi90 Profilo | Senior Member

Gia per la progressbar tu devi fissare un valore massimo ed un valore attuale che indica la percentuale se cosi la vogliamo intendere, completata, quindi utilizzando il metodo open() per aprire la connessione, tu non puoi sapere la percentuale di progresso dell'apertura della connessione, potresti fare una cosa del genere sulla lettura dal database di n record dal database, dove fai un operazione del genere

//Ottieni il numero di tutti gli elementi da selezionare presenti nella tabella
OleDbCommand Com=new OleDbCommand("SELECT Count(*) FROM Tabella1",conn);
int num=int.Parse(Com.ExecuteScalar().ToString());

progressbar1.Maximum = num;

e poi alla lettura:
Com.CommandText="SELECT * FROM Tabella1";

DataReader rr=Com.ExecuteReader();
while(rr.Read()){
//Alla lettura di ogni record incrementi la progressbar
progressbar1+=1;
}

Solo in operazioni del genere puoi utilizzare la progressbar, per non impegnare l'interfaccia ti consiglio di affidarti ai Thread e nel frattempo visualizzare un messaggio tipo "Attendere connessione al database in corso"

trinity Profilo | Guru

si vero anche questo ma a me era un discorso di rendere + bella la grafica.
Stavo utilizzando il backgroundWorker1 e ho scritto così:


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

funziona in parte perchè appena il codice passa sulla riga Me.ToolStripButton3.Enabled = True ecc il compilatore genera un errore di questo tipo:

Operazione cross-thread non valida: è stato eseguito l'accesso al controllo 'ToolStrip1' da un thread diverso da quello da cui è stata eseguita la creazione.

se riesco a risolvere questo errore allora potrò utilizzare la progressbar come volevo io...

Ps. e se volessi utilizzare la progressbar per altri lavori dove conosco il max del valore come posso utilizzare l'oggetto BackgroundWorker1, vedevo la proprietà ProgressPercentage(interessante) sai dirmi qualcosa in +?

Ciao

Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

gigi90 Profilo | Senior Member

Qundo accedi alla toolstrip ti da un errore perche la procedura che tenta di impostare la toolstrip si trova in un thread per l'appunto quello creato dal backgroun worker, mentre invece la toolstrip si trova in una altro thread ossia il thread principale cioè quello del form, ora per poter impostare le proprietà della toolstrip, il pezzo di codice che imposta la toolstrip, deve essere chiamato dal thread esterno cioè quello del backgroundworker, ma eseguito in quello principale per poter settare le proprietà a tuo piacimento, una cosa del genere la puoi fare nel modo seguente:

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

denis.basei Profilo | Senior Member

L'errore probabilmente è dovuto la fatto che hai fatto accesso ad un controllo del form dal thread secondario, cosa che non è possibile fare. Dalla sub backgroundworker1_DoWork NON puoi accedere all'interfaccia utente. Usa il metodo ReportProgress nel thread secondario, questo fa scattare l'evento ProgressChanged che viene eseguito nel thread principale.

Per quel che riguarda l'aggiornamento di progressbar.value lo devi sempre fare nella sub ..._ProgressChanged ed il valore che gli assegni è la proprietà e.progresspercentage. Il metodo ReportProgress lo puoi chiamare quante volte vuoi dalle tue routine passando nel primo parametro il valore da assegnare alla progressbar.


Spero di averti dato qualche indicazione utile.


Denis

trinity Profilo | Guru

scusami ma per thread secondario nel mio esempio tu cosa intendi? ed il metodo ReportProgress serve a richiamare il codice che viene scritto nell'evento ProgressChanged, giusto?


Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

denis.basei Profilo | Senior Member

Nel tuo esempio la routine "connessione", che è quella nella quale viene generato l'errore, è stata chiamata dal backgroundworker_dowork per cui fa parte anche questa del thread secondario. Quanto dici su ProgressChanged e ReportProgress è corretto.

trinity Profilo | Guru

senti io ho fatto così, dimmi se va bene:

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

dammi il tuo parere oppure se puoi correggi nel meglio il mio codice :-)

Ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

denis.basei Profilo | Senior Member

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'==========AVVIO LA CONNESSIONE AL DATABASE==========
Me.PRogressBar1.Visible = True
Me.BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
connessione()
End Sub

Private Sub _connessione()
Db.ConnectionString = "Data Source=SQLB10.WEBCONTROLCENTER.COM,1433;Network Library=DBMSSOCN;Initial Catalog=C59onlinefr;User ID=pippo;Password=pluto;"
Db.Open()
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If Db.State = ConnectionState.Closed = True Then
ProgressBar1.Visible = False
End If
If Db.State = ConnectionState.Open = True Then
' ** Lascio a True altrimenti non c'è differenza fra True e False
ProgressBar1.Visible = True
End If
End Sub

' Resto dell'idea che la progress bar per l'apertura di una connessione non è molto comodo
' perchè il processo rimane fermo sull'istruzione db.open finchè la connessione non si è
' aperta oppure non va in timeout.
' Una progress bar potrebbe andar bene se ci sono delle operazioni ricorsive. Un esempio banale:
' immagina di avere un ciclo da 0 a 100 e di voler aggiornare contestualmente una progress
' bar...
Privare Sub Connessione()
for Conta as integer = 0 to 100
Me.BackgroundWorker1.ReportProgress(Conta)
Next Conta
end sub

Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage
end sub


Ciaooo, denis
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-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5