Отображение прогресса при загрузке данных - PullRequest
1 голос
/ 25 января 2011

Я использую следующий код, расположенный здесь для загрузки файлов

Public Function UploadFile(ByVal oFile As FileInfo) As Boolean
Dim ftpRequest As FtpWebRequest
Dim ftpResponse As FtpWebResponse
Try
ftpRequest = CType(FtpWebRequest.Create(FTPSite + CurrentDirectory + oFile.Name), _
    FtpWebRequest)
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile
ftpRequest.Proxy = Nothing
ftpRequest.UseBinary = True
ftpRequest.Credentials = New NetworkCredential(UserName, Password)
ftpRequest.KeepAlive = KeepAlive
ftpRequest.EnableSsl = UseSSL
If UseSSL Then ServicePointManager.ServerCertificateValidationCallback = _
    New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate)
Dim fileContents(oFile.Length) As Byte
Using fr As FileStream = oFile.OpenRead
fr.Read(fileContents, 0, Convert.ToInt32(oFile.Length))
End Using
Using writer As Stream = ftpRequest.GetRequestStream
writer.Write(fileContents, 0, fileContents.Length)
End Using
ftpResponse = CType(ftpRequest.GetResponse, FtpWebResponse)
ftpResponse.Close()
ftpRequest = Nothing
Return True
Catch ex As WebException
Return False
End Try
End Function

Я хотел бы расширить его, чтобы я тоже мог иметь процесс загрузки.Проблема в том, что я не знаю с чего начать.Какова «логика» отображения хода загрузки?

«Разделить файл» на предопределенные части и загрузить их или как?

Ответы [ 2 ]

4 голосов
/ 02 февраля 2011

Вам необходимо выполнить запрос на загрузку в фоновом потоке, чтобы избежать блокировки потока пользовательского интерфейса. Самый простой способ сделать это - использовать класс BackgroundWorker. Он разработан специально для таких ситуаций.

    Dim backgroundWorker As New System.ComponentModel.BackgroundWorker()
    backgroundWorker.WorkerReportsProgress = True
    backgroundWorker.WorkerSupportsCancellation = True
    AddHandler backgroundWorker.DoWork, AddressOf Me.BackgroundFileDownload
    AddHandler backgroundWorker.ProgressChanged, AddressOf Me.ProgressChanged
    AddHandler backgroundWorker.RunWorkerCompleted, AddressOf Me.JobCompleted

События ProgressChanged и RunWorkerCompleted запускаются в потоке пользовательского интерфейса и позволяют обновлять индикатор выполнения в соответствии с текущим состоянием загрузки. Они будут выглядеть примерно так:

Protected Sub ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        progressBar.Value = e.ProgressPercentage
End Sub

DoWork вызывается в фоновом потоке и там, где вы хотите вызвать функцию UploadFile (), которую вы написали. Для FtpWebRequest вы сначала захотите получить размер файла, а затем, когда вы загружаете блоки данных, разделите то, что вы загрузили, на полный размер файла, чтобы получить процент выполнения. Что-то вроде

Worker.ReportProgress(Math.Round((_bytesUploaded / _fileSize) * 100))

Надеюсь, это поможет.

1 голос
/ 02 февраля 2011

Я не уверен, работает ли этот код в форме Windows или на веб-странице, что может повлиять на то, как вы на самом деле будете показывать прогресс.Но в любом случае, вы сначала хотели бы, чтобы этот метод сообщал о прогрессе в том, насколько он далеко.

Для этого лучше всего использовать события.Вот что вам нужно добавить к этому классу и функции:

Сначала класс, содержащий процент:

Public Class ProgressEventArgs
    Inherits System.EventArgs

    Public Sub New(ByVal pPercentage As Decimal)
        _Percentage = pPercentage
    End Sub

    Private _Percentage As Decimal
    Public ReadOnly Property Percentage() As Decimal
        Get
            Return _Percentage
        End Get
    End Property

End Class

Затем вы захотите добавить событие в класс, которыйUpLoadFile принадлежит:

Public Event Progress(ByVal sender As Object, ByRef e As ProgressEventArgs)

Наконец, в UpLoadFile вы захотите вызвать это событие:

....
writer.Write(fileContents, 0, blockread) 
    RaiseEvent Progress(Me, new ProgressEventArgs(100 * block / blocks))
Next
....

Откуда бы вы ни вызывали это, вы можете прослушать событие:

Private Sub HandleProgress(ByVal sender As Object, ByRef e As ProgressEventArgs)
    '.... Update screen
End Sub

....
AddHandler YourUploadClass.Progress AddressOf HandleProgress
...