Итак, я вот-вот убью это на некоторое время. Я программист-любитель, и поэтому я не всегда знаю, что я делаю неправильно.Асинхронный загрузчик WebClient не работает должным образом
Во всяком случае, предпосылка моего недавнего проекта:
Моих друзья и я регулярно играть Minecraft, но они не очень яркими, и мы не всегда вокруг, чтобы получить моды и отправить их ссылку и этажерку , Поэтому я подумал, что буду программировать что-то, чтобы автоматически вытаскивать моды, чтобы они синхронизировались с сервером и одновременно получали данные сервера.
Я использую бесплатный хост FTP, но я не думаю, что это проблема здесь, по причинам, которые станут ясными.
В принципе, я хочу использовать индикатор прогресса и, в идеале, метку, чтобы указать прогресс общего блока данных (все моды вместе ... не более 1 ГБ - немного меньше). Тем не менее, я, кажется, работаю в нескольких вопросов, связанных с возможностью асинхронного:
Это будет случайным образом выбрать опции не загружать файлы, которые должны быть скачиванием
Он не может загружать файлы в полном объеме до подачи заявления должно быть заполнено
Ошибка выполнения может составлять 50% при запуске msgbox, говоря, что он завершил загрузку всех элементов.
Однако, в то время как прогрессбар не работает из-за событий отчетности для прогресса не существует в синхронном использовании Webclient, когда я бегу синхросигнала в BGworker, он загружает должным образом каждый раз. Тем не менее, я теряю на текущую отчетность, которая является своего рода важно ....
Так, в основном:
- Есть ли лучший способ осуществить это?
Это последний кусок, который мне нужно для работы, прежде чем он готов к работе, поэтому я действительно хотел бы попробовать и сделать это. Спасибо за любую помощь!
Edit: обновление с кодом:
Public Function GetDownloadSize(ByVal URL As String) As Long
Dim request As Net.FtpWebRequest = DirectCast(Net.WebRequest.Create(URL), Net.FtpWebRequest)
request.Method = Net.WebRequestMethods.Ftp.GetFileSize
request.Credentials = New Net.NetworkCredential(dl_user, dl_pass)
Dim response As Net.FtpWebResponse = DirectCast(request.GetResponse(), Net.FtpWebResponse)
Dim fileSize As Long = response.ContentLength
Return fileSize
End Function
Private Sub btn_sync_Click(sender As Object, e As EventArgs) Handles btn_sync.Click
Dim cont As DialogResult = MsgBox("Continue? " + (total_dl_size/1000).ToString("N0") + " KB remain to be downloaded.", MsgBoxStyle.YesNo, "CAUTION!")
If cont = DialogResult.No Then
tb_warnings.AppendText("-ERR: User declined to synchronize files. Restart the application to sync.")
tb_warnings.AppendText(ControlChars.NewLine)
Label3.BackColor = Color.Firebrick
Return
End If
btn_sync.Enabled = False
btn_scan.Enabled = false
tb_warnings.AppendText("-Deleting outmoded/unused mods. Protected mods will be kept.")
For Each i As fdata_obj In deleted_files
My.Computer.FileSystem.DeleteFile(mc_dir + "\mods\" + i.name)
Next
tb_warnings.AppendText(ControlChars.NewLine)
tb_warnings.AppendText("-Deleting mod subdirectories to ensure no conflicts.")
tb_warnings.AppendText(ControlChars.NewLine)
For Each d In My.Computer.FileSystem.GetDirectories(mc_dir + "\mods")
My.Computer.FileSystem.DeleteDirectory(d, FileIO.DeleteDirectoryOption.DeleteAllContents)
Next
initialize_download()
End Sub
Private Sub initialize_download()
Dim wc As New System.Net.WebClient() ' SORRY, ASSUME THIS IS A PUBLIC VAR SO IT CAN BE REFERENCED ACROSS ITS OTHER METHODS
AddHandler wc.DownloadProgressChanged, AddressOf OnDownloadProgressChanged
AddHandler wc, AddressOf OnFileDownloadCompleted
Dim usr As String = "randouser"
Dim pass As String = "randopass"
For Each s In (From dl As fdata_obj In new_files Select dl_server + "/mods/" + mods_dir + "/" + dl.name).ToList
downloads.Enqueue(s)
Next
wc.Credentials = New Net.NetworkCredential(usr, pass)
Dim urix As String = downloads.Dequeue
Try
wc.DownloadFileasync(New Uri(urix), mc_dir + "\mods\" + IO.Path.GetFileName(urix))
Catch ex As Exception
MsgBox(ex.Message)
If tb_warnings.InvokeRequired = True Then
tb_warnings.Invoke(New tb_updater(AddressOf tb_update), "-ERR: Could not download file: " + urix, urix)
Else
tb_warnings.AppendText("-ERR: Could not download file: " + IO.Path.GetFileName(urix))
tb_warnings.AppendText(ControlChars.NewLine)
End If
end try
End Sub
Private Sub OnDownloadProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs)
MsgBox("This is happening!")
total_dl = total_dl + e.BytesReceived
Dim percentage As Integer = (CType((total_dl/total_dl_size), Integer) * 100)
if percentage > 100 then
percentage = 100
endif
prog_update(percentage)
End Sub
delegate sub progress_update(byval prog as integer)
' POTENTIAL ISSUES HERE???????
private sub prog_update(byval prog as integer)
if progressbar1.invokerequired then
progressbar1.invoke(new prog_update(addressof progress),prog)
else
progressbar1.value = prog
Private Sub OnFileDownloadCompleted(ByVal sender As Net.WebClient, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
If e.Cancelled Then
MsgBox(e.Cancelled)
ElseIf Not e.Error Is Nothing Then
MsgBox(e.Error.Message)
Else
if downloads.count > 0 then
Dim urix As String = downloads.Dequeue
Try
wc.DownloadFileasync(New Uri(urix), mc_dir + "\mods\" + IO.Path.GetFileName(urix))
Catch ex As Exception
MsgBox(ex.Message)
If tb_warnings.InvokeRequired = True Then
tb_warnings.Invoke(New tb_updater(AddressOf tb_update), "-ERR: Could not download file: " + urix, urix)
Else
tb_warnings.AppendText("-ERR: Could not download file: " + IO.Path.GetFileName(urix))
tb_warnings.AppendText(ControlChars.NewLine)
End If
End Try
End If
End Sub
«WebClient» отлично работал в последний раз, когда я проверил. Пожалуйста, покажите нам свой код. –
@VisualVincent # 1: Хорошее имя пользователя, # 2: Отредактированное сообщение, чтобы показать код.Этот вызов функции делегирования функции может быть немного отключен, так как я переписываю этот код без преимущества IDE и не совсем помню формат. Будьте уверены, шаблон звонка правильный в моем исходном коде. –
** 1: ** Спасибо;) ** 2: ** Хорошо, я просто запустил мой компьютер, тогда я попробую код. –