2013-11-22 28 views
0

我想知道为什么这段代码不工作,它不会引发任何异常,文件被下载,只是事件不是。Webclient下载EventArgs不能在FTP上工作

我已经尝试了与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 
+1

你要在这里http://msdn.microsoft.com/en-us/library/system.net.webclient.downloadprogresschanged%28v=vs.110%29.aspx?cs-save看看-lang = 1&cs-lang = vb#code-snippet-1 – K3rnel31

+0

@ K3rnel31感谢您的文档,但对我而言有点不清楚(奇怪),那意味着什么事情只会由DownloadFileAsync webclient方法引发?我看到是的,他们是通过这种方法提出的,但是这给我带来了两个问题。我不明白为什么只有异步可以引发这种事件。 2.我得到这个eventhandlers错误'不能转换类型'System.ComponentModel.AsyncCompletedEventArgs'键入'System.Net.DownloadDataCompletedEventArgs''。 PS:对不起我的英语。 – ElektroStudios

+0

ok我已经将方法签名更改为'byval e AsyncCompletedEventArgs',但随后在引发下载事件时抛出“object not set refence”异常,但仍未解决。 – ElektroStudios

回答

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 

末级

+0

不,这是完全不正确的,变量声明的'WithEvents'关键字让对象引发事件。 – ElektroStudios

+0

是的,它允许对象引发事件,但为了让您的处理程序订阅它们,您需要使用addhandler在运行时将其挂起。你为什么不试试呢? – peterG

+0

使用与您不再需要的事件手动添加手柄。 “你为什么不试试呢?”你不应该假设,我已经尝试过了(即使确定addhandler不是必须的),我已经尝试过了,没有任何反应。谢谢反正 – ElektroStudios

1

独特的原因事件不会升高(如前面所说的由@ K3rnel31上面的评论)是,只有异步webclient方法引发这些事件,那么解决这个问题的唯一方法就是使用异步方法,并且实际上不需要使用阻塞方法来引发事件当第一次尝试提交webclient事件时,它让我感到有点困惑,我没有想到我想用正确的逻辑来做什么。

注:而只是为了澄清,当然也没有必要在运行时手动ADDRES处理程序到 已被宣布与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 

然后处理事件(仅适用于异步方法ofcourse)我做这个:

请注意,存在两个webclients对象,因为单个webclient不能同时上载为异步,因为它会尝试下载异步,所以它应该抛出异常,然后我使用一个客户端上传和其他downloa DS。

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