Classe WebClient Visual Studio 2005

martedì 10 aprile 2012 - 01.24
Tag Elenco Tags  VB.NET  |  .NET 2.0  |  Windows XP  |  Visual Studio 2005  |  SQL Server 2005  |  Chrome  |  Crystal Reports XI

pulce2010 Profilo | Newbie

Salve, ho un problemino con una mia applicazione.
Utilizzo la classe web client dichiarando l'oggetto
Private client As New Net.WebClient
come variabile globale della mia classe.

Vorrei scaricare da un sito ftp un particolare eseguibile (6 MB) .
Nella mia form ci sono una progress bar, una label, due button (Scarica e Annulla) e un BackgroundWorker
Usando la classe web client riesco nei miei intenti col seguente codice.


_____________________________________________________________________________________________________
Private Sub Scarica_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Scarica.Click
Scarica.Enabled = False
Annulla.Enabled = True
BackgroundWorker1.RunWorkerAsync()
ProgressBar1.Visible = True
End Sub

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Try
Dim client As New Net.WebClient
AddHandler client.DownloadProgressChanged, AddressOf client_ProgressChanged

AddHandler client.DownloadFileCompleted, AddressOf client_DownloadCompleted

Dim uri As Uri = New Uri("ftp://ftp.xxx/yyy.exe")
client.Credentials = New Net.NetworkCredential("aaa", "bbb")
client.DownloadFileAsync(uri, "C:\yyy.exe")
Catch ex As Exception
MsgBox("Error, Registration with the server was Unsuccesful", MsgBoxStyle.Critical, "Error!")
End Try

End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Scarica.Enabled = True
ProgressBar1.Visible = False
End Sub

Private Sub client_ProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)

Dim bytesIn As Double = Double.Parse(e.BytesReceived.ToString())
Dim totalBytes As Double = Double.Parse(e.TotalBytesToReceive.ToString())
Dim percentage As Double = bytesIn / totalBytes * 100
ProgressBar1.Value = Int32.Parse(Math.Truncate(percentage).ToString())

End Sub
Private Sub client_DownloadCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)

MessageBox.Show("Download Completato")
Scarica.Enabled = True


End Sub

Private Sub Annulla_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Annulla.Click
client.CancelAsync()
MsgBox("Hai interrotto il download", MsgBoxStyle.Critical)
ProgressBar1.Value = 0
Label1.Text = "0 %"
End Sub
_________________________________________________________________________

Riesco a scaricare l'exe ma non riesco a gestirlo all'interno della progress bar, esce un errrore all'istruzione
ProgressBar1.Value = Int32.Parse(Math.Truncate(percentage).ToString())
con problemi di massimo e minimo.
Oltre a questo la funzione cancelasyinc che dovrebbe stoppare il dowload non funziona.

Grazie mille in anticipo.

InsettoScoppiettato Profilo | Junior Member

In passato ho usato una progress bar per uno scopo simile e ti allego qui sotto i due metodi fondamentali che ho usato ( il codice è C# ma direi che è equivalente, i metodi erano del Form su cui la progresbar risiede):

private void BarSetUp(int tot_sims) { progressBarSimulation.Minimum = 0; barScale = 100 / (double)tot_sims; //barScale è una variabile del form di tipo double progressBarSimulation.Maximum = 100; BarUpdate(0); } delegate void SetRefreshCallback(int n); private void BarUpdate(int sim) { if (this.progressBarSimulation.InvokeRequired) { SetRefreshCallback d = new SetRefreshCallback(BarUpdate); this.Invoke(d, new object[] { sim }); } else { progressBarSimulation.Value = (int)(sim * barScale); progressBarSimulation.Refresh(); } }


Il mio metodo update era usato in un call back da un'altro processo e per questo non ho caricato l'evento ProgressChanged ( infatti il mio update prendeva un intero solamente senza il sender). IN sostanza comunque, con un primo metodo ( che tu dovresti lanciare al click del button scarica) inizializzo i valori massimi e minimi della progressbar (condizione questa necessaria per dare un valore logico ed utilizzabile alla variabile Value della progressbar). Con il secondo, cambiavo ogni volta che volevo il valore di Value e con il refresh aggiornavo il controllo a video.

Tu dovresti quindi appena inizi il download dargli i valori MIn e max pari a 0 e 100 (se vuoi continuare a usare percentage come riferimento progress), e poi con il tuo metodo di cambi il valore e poi fai il refresh!

Per quanto riguarda la cancellazione, a aprte il fatto che non conosco CancelAsync() nel dettaglio, ma suppondo the eviti di fare una request web e non interrompe un flusso su porta già aperto. direi che finchè non premi Ok sulla messageBox non passi all'istruzione ProgressBa.value = 0;

Non ho idea di come lo farebbe un purista,ma io associerei al form un timer che ticka ogni secondo quando un download è attivo (in pratica che parte ogni volta che premi Download - quindi il primo bottone sul suo click) e controlla una variabile globale bool chiamata per esempio downloadToBeCanceled, che sta sempre a false. Viene messa a true quando premi il pulsante cancella e al prossimo tick del timer entri in un'istruzione if che ferma il download (probabilmente con un invoke callback visto che il processo sta su un worker).

UN'ultima nota sul secondo metodo che ti ho postato sopra: contiene un grosso if che lo divide in due: se entri nell'if significa che il processo da cui vuoi manipolare il controllo è diverso dal processo corrente che governa il form, allora questo fa in modo che sia il form ad invocare di nuovo il metodo Update. Quando questo viene chiamato una seconda volta dal Form a questo punto non entra nell'if ed esegue le due linee vere e proprie (senza dare eccezioni strane dovute al cross thread) e setta la proprietà value ed esegue il refresh().

Spero aiuti
ciao

Alessandro Parma
Programmazione multipla scoposta con prognosi ancora da definirsi

pulce2010 Profilo | Newbie

Ciao, grazie per le dritte che ho valutato in modo positivo, infatti l'oggetto BackgroundWorker non mi è più servito e sono andato a gestire l'evento DownloadProgressChanged della classe Net.WebClient .

Di sotto metto il codice con cui ho risolto.
Form frmDownload con una progressbar, tre pulsanti, scarica, annulla e esci.

Imports System.net
Imports System.IO
Imports System.Windows.Forms

Public Class frmDownload
Private client As New Net.WebClient
Dim fileSize As Double


Private Sub frmDownload_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

ProgressBar1.Visible = True
Annulla.Enabled = False
Esci.Enabled = True

End Sub



Private Sub Scarica_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Scarica.Click
Me.Cursor = Cursors.WaitCursor
Annulla.Enabled = True
Dim FtpRequest As Net.FtpWebRequest
Dim FtpResponse As Net.FtpWebResponse


FtpRequest = Net.FtpWebRequest.Create("ftp://xxx/xxx.exe")
FtpRequest.Credentials = New System.Net.NetworkCredential("a", "b")
FtpRequest.Proxy = Nothing
FtpRequest.Method = Net.WebRequestMethods.Ftp.GetFileSize
FtpResponse = FtpRequest.GetResponse
fileSize = FtpResponse.ContentLength

AddHandler client.DownloadProgressChanged, AddressOf ProgressChanged
AddHandler client.DownloadFileCompleted, AddressOf DownloadFileCompleted

ProgressBar1.Value = 0

Dim uri As Uri = New Uri("ftp://xxx/xxx.exe")
client.Credentials = New Net.NetworkCredential("a", "b")
client.Proxy = Nothing
client.DownloadFileAsync(uri, Application.StartupPath & "\xxx.exe")





End Sub

Private Sub DownloadFileCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
If e.Cancelled Then
ProgressBar1.Value = 0
Else
If e.Error Is Nothing Then
MsgBox("Download File Completato")
Scarica.Enabled = True
Annulla.Enabled = False
Esci.Enabled = True
ProgressBar1.Value = 0
Me.Cursor = Cursors.Default
Process.Start(Application.StartupPath & "\xxx.exe")
Global.System.Windows.Forms.Application.Exit()

Else
MsgBox(e.Error.Message)
Scarica.Enabled = True
Annulla.Enabled = False
Esci.Enabled = True
ProgressBar1.Value = 0
Me.Cursor = Cursors.Default
End If

End If



End Sub

Private Sub ProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs)
Dim bytesIn As Double = Double.Parse(e.BytesReceived.ToString())

Dim percentage As Double = bytesIn / fileSize * 100
ProgressBar1.Value = Int32.Parse(Math.Truncate(percentage).ToString())

End Sub

Private Sub Annulla_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Annulla.Click
client.CancelAsync()
MsgBox("Hai interrotto il download", MsgBoxStyle.Critical)
ProgressBar1.Value = 0
Esci.Enabled = True
Scarica.Enabled = True
Annulla.Enabled = False
ProgressBar1.Value = 0
Me.Cursor = Cursors.Default
End Sub

Private Sub Esci_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Esci.Click

Global.System.Windows.Forms.Application.Exit()

End Sub
End Class
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