VB.Net网络客户端上载挂起

VB.Net网络客户端上载挂起,vb.net,ftp,webclient,Vb.net,Ftp,Webclient,我有多个文件要使用以下代码上载(到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 credential

我有多个文件要使用以下代码上载(到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
Private子上传文件(ByVal本地作为字符串)
如果wc.IsBusy=True,则抛出新异常(“上载已在进行!”)
wc.Credentials=newnetworkcredential(usr.ToString,pass.ToString)'设置凭据。
“total_dl_size=GetDownloadSize(url)”获取当前文件的大小。
尝试
Dim FileName As String=Path.GetFileName(local)'获取当前文件的名称。
附录警告(“上载”和文件名&“…”)下载通知。
wc.UploadFileAsync(新Uri(info_srv&local),Path.Combine(mc_dir,local))'将文件下载到桌面(在此处使用您自己的路径)。
特例
AppendWarning(“-ERR:无法下载文件:”&local&ControlChars.NewLine)
结束尝试
端接头
私有子附件警告(ByVal文本作为字符串)
如果需要tb_warnings.invoker,则
tb_warnings.Invoke(Sub()tb_warnings.AppendText(Text))
其他的
tb_警告。追加文本(文本)
如果结束
端接头
私有子wc_UploadProgressChanged(发送方作为对象,e作为System.Net.UploadProgressChangedEventArgs)处理wc.UploadProgressChanged
总计=e.BytesSent
以整数表示的Dim进度=CType(数学四舍五入((基线+总大小)*100)/总大小,整数)
如果需要ProgressBar1.Invoker,则
ProgressBar1.Invoke(Sub()
如果进度>100,则进度=100
如果进度<0,则进度=0
ProgressBar1.Value=进度
末端接头)
其他的
如果进度>100,则进度=100
如果进度<0,则进度=0
ProgressBar1.Value=进度
如果结束
如果需要lbl_progress.invoker,则
lbl_progress.Invoke(Sub()lbl_progress.Text=((总ul+baseline)/1024).ToString(“N0”)和“KB/”&(总ul\u size/1024).ToString(“N0”)和“KB”)
其他的
lbl_progress.Text=((总长度+基线)/1024)。ToString(“N0”)和“KB/”&(总长度/1024)。ToString(“N0”)和“KB”&“progress.ToString&%”
如果结束
端接头
私有子wc_uploadFileCompleted(发送方作为对象,e作为System.ComponentModel.AsyncCompletedEventArgs)处理wc.UploadDataCompleted
如果e.取消,则
MessageBox.Show(如已取消)
否则,错误就什么都不是了
MessageBox.Show(例如Error.Message)
其他的
如果files.Count>0,则
AppendWarning(“上传完成!”&ControlChars.NewLine)
基线=基线+总
Dim file As String=files.Dequeue()
MsgBox(文件)
UploadFile(文件)'下载下一个文件。
其他的
AppendWarning(“所有上传完成!”&ControlChars.NewLine)
如果结束
如果结束
然而,使用我的两个测试文件,它总是在我给出的第一个文件的结尾处停止,而不会进入第二个文件

但是,我有一个FTP客户端连接到同一台服务器,当我刷新时,我可以看到(至少第一个文件)数据被正确上传

关于这里出了什么问题,有什么建议吗

编辑、记录:


谢谢你的帮助

这对我很有效……我试着模仿我认为你的样子。我测试了一个由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配置来进行跟踪,但似乎是由于开销导致上传失败。此后,我发现ftp的xml集更容易修改,文件现在可以正确上传。谢谢大家

是否调用
wc\u UploadProgressChanged
wc\u uploadFileCompleted
?同步上传也有同样的问题吗?“停止”到底是什么意思?给我们看一张进度表。@MartinPrikryl进度是,似乎没有完成。我还没有尝试同步,顺便说一下,我的队列中有一个11KB的文件,作为第一个文件,没有明显的下载进度超过11KB-1。它没有考虑文件完成,因此,没有其他上传进度。当我明天回到我的系统时,我将尝试上传日志。请注意:如果我在这里说下载,那是因为我的大脑混乱。所有这些实例都可以用upload替换。这与您的问题有点离题,但您不应该为每个控件选中
invokererequired
。检查一次,然后更新相同的
If
-语句。您可以只检查
Me.invokererequired
,因为调用将始终由当前表单完成(即,即使您调用
yourControl.Invoke()
)。我要说的是,您可以通过执行以下操作来最小化用于调用的代码:,这:--除了减少代码之外,它做的事情与当前代码完全相同,只是它只调用一次。:)@VisualIncent我上传了从网络跟踪生成的日志的尾部。旁边的文件名是mods存储为的.jar文件的组件。出于测试目的,我试图上传的完整文件是:AcademyCraft-1.0pr2_1.jar AgriCraft-1.7.10-1.4.6-Hotfix我怀疑这可能是文件量太少,但我将实现这一点并查看。作为比较,我使用的两个文件的大小为27MB(25.5和1.6)。不过,我可以使用实际的FTP将这些文件上传到主机,所以我认为没有限制。无论如何,我会试试你的解决方案,看看它是否有效。更新:它仍然挂起。我想这和文件量有关。我正在尝试其他FTP库