2013-11-22 31 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