VB.Net Webclient 上传挂起
VB.Net Webclient Upload Hanging
我有多个文件要使用此代码上传(到 FTP 服务器):
Private Sub UploadFile(ByVal local As String)
If wc.IsBusy = True Then Throw New Exception("An upload is already ongoing!")
wc.Credentials = New NetworkCredential(usr.ToString, pass.ToString) 'Set the credentials.
'total_dl_size = GetDownloadSize(url) 'Get the size of the current file.
Try
Dim FileName As String = Path.GetFileName(local) 'Get the current file's name.
AppendWarning("Uploading " & FileName & "... ") 'Download notice.
wc.UploadFileAsync(New Uri(info_srv & local), Path.Combine(mc_dir, local)) 'Download the file to the desktop (use your own path here).
Catch ex As Exception
AppendWarning("-ERR: Could not download file: " & local & ControlChars.NewLine)
End Try
End Sub
Private Sub AppendWarning(ByVal Text As String)
If tb_warnings.InvokeRequired Then
tb_warnings.Invoke(Sub() tb_warnings.AppendText(Text))
Else
tb_warnings.AppendText(Text)
End If
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As System.Net.UploadProgressChangedEventArgs) Handles wc.UploadProgressChanged
total_ul = e.BytesSent
Dim Progress As Integer = CType(Math.Round((baseline + total_ul) * 100) / total_ul_size, Integer)
If ProgressBar1.InvokeRequired Then
ProgressBar1.Invoke(Sub()
If Progress > 100 Then Progress = 100
If Progress < 0 Then Progress = 0
ProgressBar1.Value = Progress
End Sub)
Else
If Progress > 100 Then Progress = 100
If Progress < 0 Then Progress = 0
ProgressBar1.Value = Progress
End If
If lbl_progress.InvokeRequired Then
lbl_progress.Invoke(Sub() lbl_progress.Text = ((total_ul + baseline) / 1024).ToString("N0") & " KB / " & (total_ul_size / 1024).ToString("N0") & " KB")
Else
lbl_progress.Text = ((total_ul + baseline) / 1024).ToString("N0") & " KB / " & (total_ul_size / 1024).ToString("N0") & " KB | " & Progress.ToString & "%"
End If
End Sub
Private Sub wc_uploadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles wc.UploadDataCompleted
If e.Cancelled Then
MessageBox.Show(e.Cancelled)
ElseIf Not e.Error Is Nothing Then
MessageBox.Show(e.Error.Message)
Else
If files.Count > 0 Then
AppendWarning("Upload Complete!" & ControlChars.NewLine)
baseline = baseline + total_ul
Dim file As String = files.Dequeue()
MsgBox(file)
UploadFile(file) 'Download the next file.
Else
AppendWarning("All Uploads Finished!" & ControlChars.NewLine)
End If
End If
但是,使用我的两个测试文件,它总是停在我给它的第一个文件的末尾,而不会继续到第二个文件。
但是,我有一个 FTP 客户端连接到同一台服务器,当我刷新时,我可以看到(至少对于第一个文件)数据正在正确上传。
关于这里出了什么问题有什么建议吗?
编辑,记录:http://pastebin.com/kqG28NGH
感谢您的帮助!
这对我有用...我试图模仿我认为你的形式。我用 8 个文件的队列进行了测试,每个文件的大小从 150K 到 400K 不等。我不太明白你想用进度条做什么。我的填充每个文件并为下一个文件重置,最后一次调用 DoUpload 时没有更多文件。希望这会有所帮助。
Imports System.IO
Imports System.Net
Public Class Form1
Const info_srv As String = "ftp://example.com/SomeFolder/"
Const usr As String = ""
Const pass As String = ""
Const mc_dir As String = "D:\Source\Folder"
Private WithEvents wc As New Net.WebClient
' Contains file names only, no paths
Private Files As New Queue(Of String)
Private Sub Button1_Click(sender As Object, e As EventArgs) _
Handles Button1.Click
wc.Credentials = New NetworkCredential(usr, pass)
' Put the work in a task so UI is responsive
Task.Run(Sub() DoUpload())
End Sub
Private Sub DoUpload()
ShowProgress("", 0)
If Files.Count > 0 Then
Dim local As String = Files.Dequeue
Dim FileName As String = Path.Combine(mc_dir, local)
AppendWarning("Uploading " & FileName & "... ")
Try
wc.UploadFileAsync(New Uri(info_srv & local), FileName)
Catch ex As Exception
AppendWarning("-ERR: Could not upload file: " & local & Environment.NewLine)
End Try
Else
AppendWarning("All Uploads Finished!" & Environment.NewLine)
End If
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As UploadProgressChangedEventArgs) _
Handles wc.UploadProgressChanged
' Do not use e.ProgressPercentage - it's inaccurate by half by design per Microsoft
With String.Format("{0} KB / {1} KB", Int(e.BytesSent / 1024).ToString("N0"), Int(e.TotalBytesToSend / 1024).ToString("N0"))
ShowProgress(.ToString, Int(e.BytesSent / e.TotalBytesToSend * 100))
End With
End Sub
Private Sub wc_UploadFileCompleted(sender As Object, e As UploadFileCompletedEventArgs) _
Handles wc.UploadFileCompleted
Select Case True
Case e.Cancelled
MessageBox.Show("Cancelled")
Case e.Error IsNot Nothing
MessageBox.Show(e.Error.Message)
Case Else
AppendWarning("Upload Complete!" & Environment.NewLine)
' I needed this just so I could see it work, otherwise too fast
Threading.Thread.Sleep(500)
DoUpload()
End Select
End Sub
Private Sub AppendWarning(ByVal Text As String)
If Me.InvokeRequired Then
Me.Invoke(Sub() AppendWarning(Text))
Else
tb_warnings.AppendText(Text)
End If
End Sub
Private Sub ShowProgress(LabelText As String, Progress As Integer)
If Me.InvokeRequired Then
Me.Invoke(Sub() ShowProgress(LabelText, Progress))
Else
Me.lbl_progress.Text = LabelText
Me.lbl_progress.Refresh()
Me.ProgressBar1.Value = Progress
Me.ProgressBar1.Refresh()
End If
End Sub
End Class
为了后代:
检查 VB 配置中的网络跟踪设置。我发现我使用了一个非常冗长的 catch-all 配置来进行跟踪,但似乎开销正在扼杀上传。从那以后,我找到了一个更精简的 focus-on-ftp 组 xml 来修改它,现在文件可以正确上传了。谢谢大家!
我有多个文件要使用此代码上传(到 FTP 服务器):
Private Sub UploadFile(ByVal local As String)
If wc.IsBusy = True Then Throw New Exception("An upload is already ongoing!")
wc.Credentials = New NetworkCredential(usr.ToString, pass.ToString) 'Set the credentials.
'total_dl_size = GetDownloadSize(url) 'Get the size of the current file.
Try
Dim FileName As String = Path.GetFileName(local) 'Get the current file's name.
AppendWarning("Uploading " & FileName & "... ") 'Download notice.
wc.UploadFileAsync(New Uri(info_srv & local), Path.Combine(mc_dir, local)) 'Download the file to the desktop (use your own path here).
Catch ex As Exception
AppendWarning("-ERR: Could not download file: " & local & ControlChars.NewLine)
End Try
End Sub
Private Sub AppendWarning(ByVal Text As String)
If tb_warnings.InvokeRequired Then
tb_warnings.Invoke(Sub() tb_warnings.AppendText(Text))
Else
tb_warnings.AppendText(Text)
End If
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As System.Net.UploadProgressChangedEventArgs) Handles wc.UploadProgressChanged
total_ul = e.BytesSent
Dim Progress As Integer = CType(Math.Round((baseline + total_ul) * 100) / total_ul_size, Integer)
If ProgressBar1.InvokeRequired Then
ProgressBar1.Invoke(Sub()
If Progress > 100 Then Progress = 100
If Progress < 0 Then Progress = 0
ProgressBar1.Value = Progress
End Sub)
Else
If Progress > 100 Then Progress = 100
If Progress < 0 Then Progress = 0
ProgressBar1.Value = Progress
End If
If lbl_progress.InvokeRequired Then
lbl_progress.Invoke(Sub() lbl_progress.Text = ((total_ul + baseline) / 1024).ToString("N0") & " KB / " & (total_ul_size / 1024).ToString("N0") & " KB")
Else
lbl_progress.Text = ((total_ul + baseline) / 1024).ToString("N0") & " KB / " & (total_ul_size / 1024).ToString("N0") & " KB | " & Progress.ToString & "%"
End If
End Sub
Private Sub wc_uploadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles wc.UploadDataCompleted
If e.Cancelled Then
MessageBox.Show(e.Cancelled)
ElseIf Not e.Error Is Nothing Then
MessageBox.Show(e.Error.Message)
Else
If files.Count > 0 Then
AppendWarning("Upload Complete!" & ControlChars.NewLine)
baseline = baseline + total_ul
Dim file As String = files.Dequeue()
MsgBox(file)
UploadFile(file) 'Download the next file.
Else
AppendWarning("All Uploads Finished!" & ControlChars.NewLine)
End If
End If
但是,使用我的两个测试文件,它总是停在我给它的第一个文件的末尾,而不会继续到第二个文件。
但是,我有一个 FTP 客户端连接到同一台服务器,当我刷新时,我可以看到(至少对于第一个文件)数据正在正确上传。
关于这里出了什么问题有什么建议吗?
编辑,记录:http://pastebin.com/kqG28NGH
感谢您的帮助!
这对我有用...我试图模仿我认为你的形式。我用 8 个文件的队列进行了测试,每个文件的大小从 150K 到 400K 不等。我不太明白你想用进度条做什么。我的填充每个文件并为下一个文件重置,最后一次调用 DoUpload 时没有更多文件。希望这会有所帮助。
Imports System.IO
Imports System.Net
Public Class Form1
Const info_srv As String = "ftp://example.com/SomeFolder/"
Const usr As String = ""
Const pass As String = ""
Const mc_dir As String = "D:\Source\Folder"
Private WithEvents wc As New Net.WebClient
' Contains file names only, no paths
Private Files As New Queue(Of String)
Private Sub Button1_Click(sender As Object, e As EventArgs) _
Handles Button1.Click
wc.Credentials = New NetworkCredential(usr, pass)
' Put the work in a task so UI is responsive
Task.Run(Sub() DoUpload())
End Sub
Private Sub DoUpload()
ShowProgress("", 0)
If Files.Count > 0 Then
Dim local As String = Files.Dequeue
Dim FileName As String = Path.Combine(mc_dir, local)
AppendWarning("Uploading " & FileName & "... ")
Try
wc.UploadFileAsync(New Uri(info_srv & local), FileName)
Catch ex As Exception
AppendWarning("-ERR: Could not upload file: " & local & Environment.NewLine)
End Try
Else
AppendWarning("All Uploads Finished!" & Environment.NewLine)
End If
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As UploadProgressChangedEventArgs) _
Handles wc.UploadProgressChanged
' Do not use e.ProgressPercentage - it's inaccurate by half by design per Microsoft
With String.Format("{0} KB / {1} KB", Int(e.BytesSent / 1024).ToString("N0"), Int(e.TotalBytesToSend / 1024).ToString("N0"))
ShowProgress(.ToString, Int(e.BytesSent / e.TotalBytesToSend * 100))
End With
End Sub
Private Sub wc_UploadFileCompleted(sender As Object, e As UploadFileCompletedEventArgs) _
Handles wc.UploadFileCompleted
Select Case True
Case e.Cancelled
MessageBox.Show("Cancelled")
Case e.Error IsNot Nothing
MessageBox.Show(e.Error.Message)
Case Else
AppendWarning("Upload Complete!" & Environment.NewLine)
' I needed this just so I could see it work, otherwise too fast
Threading.Thread.Sleep(500)
DoUpload()
End Select
End Sub
Private Sub AppendWarning(ByVal Text As String)
If Me.InvokeRequired Then
Me.Invoke(Sub() AppendWarning(Text))
Else
tb_warnings.AppendText(Text)
End If
End Sub
Private Sub ShowProgress(LabelText As String, Progress As Integer)
If Me.InvokeRequired Then
Me.Invoke(Sub() ShowProgress(LabelText, Progress))
Else
Me.lbl_progress.Text = LabelText
Me.lbl_progress.Refresh()
Me.ProgressBar1.Value = Progress
Me.ProgressBar1.Refresh()
End If
End Sub
End Class
为了后代:
检查 VB 配置中的网络跟踪设置。我发现我使用了一个非常冗长的 catch-all 配置来进行跟踪,但似乎开销正在扼杀上传。从那以后,我找到了一个更精简的 focus-on-ftp 组 xml 来修改它,现在文件可以正确上传了。谢谢大家!