2011-01-25 3 views
1

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

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 

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

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

ответ

1

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

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

Первый класс проведения Процент:

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 
.... 

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

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

.... 
AddHandler YourUploadClass.Progress AddressOf HandleProgress 
4

Вам нужно выполнить запрос на загрузку в фоновом потоке, чтобы избежать блокировки потока пользовательского интерфейса. Самый простой способ сделать это - использовать класс 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)) 

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

Смежные вопросы