Web客户端下载EventArgs无法在FTP上运行

时间:2013-11-22 19:27:40

标签: .net vb.net ftp webclient webclient-download

我想知道为什么这段代码不起作用,它不会抛出任何异常,文件被下载,只是事件不是。

我已尝试使用webclient上传EventArgs并且它们有效,但下载EventArgs却没有。

Private WithEvents client As New System.Net.WebClient()
ftp.DownloadFile(client, "/inputfile.ext", "c:\targetfile.ext")

Private Sub Client_DownloadProgress(ByVal sender As WebClient,
                                    ByVal e As DownloadProgressChangedEventArgs) _
Handles client.DownloadProgressChanged
    MsgBox(e.ProgressPercentage & "%")

End Sub

Private Sub Client_DownloadCompleted(ByVal sender As WebClient, 
                                     ByVal e As DownloadDataCompletedEventArgs) _
Handles client.DownloadFileCompleted
    MsgBox(e.Result.ToString)
End Sub

ftp对象DownloadFile方法是这样的:

Public Sub DownloadFile(ByRef DownloadClient As WebClient,
                        ByVal filepath As String,
                        ByVal localfilepath As String,
                        Optional ByVal Asynchronous As Boolean = False)

    If filepath.StartsWith("/") Then
        filepath = Me.host & filepath
    Else
        filepath = Me.host & "/" & filepath
    End If

    With DownloadClient
        .Credentials = New NetworkCredential(Me.user, Me.pass)
        If Asynchronous Then
            .DownloadFileAsync(New Uri(filepath), localfilepath)
        Else
            .DownloadFile(New Uri(filepath), localfilepath)
        End If
    End With

End Sub

2 个答案:

答案 0 :(得分:2)

Imports System.Net

Public Class Form1

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click




    Dim w As New WebClient

    AddHandler w.DownloadProgressChanged, AddressOf downloadprogresschangedcallback
    AddHandler w.DownloadFileCompleted, AddressOf downloadfilecompletedcallback

    Dim address As String = "ftp://ftp.microsoft.com/ResKit/win2000/ADSizer.exe"

    Dim arg1 As System.Uri = New System.Uri(address)
    Dim arg2 As String = "C:\test\ADSizer.exe"

    w.DownloadFileAsync(arg1, arg2)


End Sub

Sub downloadprogresschangedcallback(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
    Debug.Print("Progress . . . ")
End Sub

Sub downloadfilecompletedcallback(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
    Debug.Print("completed")
End Sub

结束班

答案 1 :(得分:1)

事件未被引发的唯一原因(如前面的评论中的@ K3rnel31所述)是只有异步webclient方法引发这些事件,然后解决它的唯一方法是使用异步方法,并且真的没有必要用阻塞方法来引发事件,当我第一次尝试提升webclient事件时,我只是有点困惑,我没想到我正在尝试用正确的逻辑做什么。

  

注意:只是为了澄清,当然没有必要在运行时手动将处理程序添加到任何变量   已使用withevents关键字声明。

在ftp类(这只是ftpclient库http://netftp.codeplex.com/的帮助类)中我写了这些方法:

''' <summary>
''' Uploads a file to FTP.
''' </summary>
''' <param name="UploadClient">Indicates the WebClient object to upload the file.</param>
''' <param name="filepath">Indicates the ftp fle path.</param>
''' <param name="localfilepath">Specifies the local path where to save the downloaded file.</param>
''' <param name="Asynchronous">Indicates whether the download should be an Asynchronous operation, 
''' to raise WebClient events.</param>
Public Sub UploadFile(ByRef UploadClient As WebClient,
                      ByVal localfilepath As String,
                      Optional ByVal filepath As String = Nothing,
                      Optional ByVal Asynchronous As Boolean = False)

    If filepath Is Nothing Then
        filepath = Me.host & "/" & New IO.FileInfo(localfilepath).Name
    ElseIf filepath.StartsWith("/") Then
        filepath = Me.host & filepath
    Else
        filepath = Me.host & "/" & filepath
    End If

    With UploadClient
        .Credentials = New NetworkCredential(Me.user, Me.pass)
        If Asynchronous Then
            .UploadFileAsync(New Uri(filepath), "STOR", localfilepath)
        Else
            .UploadFile(New Uri(filepath), "STOR", localfilepath)
        End If
    End With
End Sub

''' <summary>
''' Downloads a file from FTP.
''' </summary>
''' <param name="DownloadClient">Indicates the WebClient object to download the file.</param>
''' <param name="filepath">Indicates the ftp fle path.</param>
''' <param name="localfilepath">Specifies the local path where to save the downloaded file.</param>
''' <param name="Asynchronous">Indicates whether the download should be an Asynchronous operation, 
''' to raise WebClient events.</param>
Public Sub DownloadFile(ByRef DownloadClient As WebClient,
                        ByVal filepath As String,
                        ByVal localfilepath As String,
                        Optional ByVal Asynchronous As Boolean = False)

    If filepath.StartsWith("/") Then
        filepath = Me.host & filepath
    Else
        filepath = Me.host & "/" & filepath
    End If

    MsgBox(filepath)
    With DownloadClient
        .Credentials = New NetworkCredential(Me.user, Me.pass)
        If Asynchronous Then
            .DownloadFileAsync(New Uri(filepath), localfilepath)
        Else
            .DownloadFile(New Uri(filepath), localfilepath)
        End If
    End With
End Sub

然后处理事件(仅针对事件的异步方法)我这样做:

请注意,存在两个webclients个对象,因为单个webclient在尝试以异步方式下载的同时无法作为异步上载,因此它应该抛出E/S异常然后我使用一个客户端上传和其他下载。

Public Class Form1

    Private WithEvents UploadClient As New System.Net.WebClient()
    Private WithEvents DownloadClient As New System.Net.WebClient()

    Private ftp As New FTP("ftp site", "username", "password")

    Private Sub Test() Handles MyBase.Shown

        ftp.Connect()
        ftp.CreateDirectory("/DirectoryName", True)
        ftp.UploadFile(UploadClient, "C:\File.txt", "/DirectoryName/NewFile.txt", False)
        ftp.DownloadFile(DownloadClient, "/DirectoryName/NewFile.txt", "c:\DownloadedFile.txt", True)

    End Sub

    Private Sub Client_UploadProgress(sender As System.Net.WebClient, e As System.Net.UploadProgressChangedEventArgs) _
    Handles UploadClient.UploadProgressChanged

        Label_Upload.Text = e.ProgressPercentage & "%"

    End Sub

    Private Sub Client_UploadCompleted(sender As System.Net.WebClient, e As System.Net.UploadFileCompletedEventArgs) _
    Handles UploadClient.UploadFileCompleted

        Label_UploadCompleted.Text = e.Result.ToString

    End Sub

    Private Sub Client_DownloadProgress(sender As System.Net.WebClient, e As System.Net.DownloadProgressChangedEventArgs) _
    Handles DownloadClient.DownloadProgressChanged

        Label_Download.Text = e.ProgressPercentage & "%"

    End Sub

    Private Sub Client_DownloadCompleted(sender As System.Net.WebClient, e As System.ComponentModel.AsyncCompletedEventArgs) _
     Handles DownloadClient.DownloadFileCompleted

        Label_DownloadCompleted.Text = "Done!"

    End Sub

End Class