【问题标题】:Webclient download EventArgs is not working on FTPWebclient 下载 EventArgs 在 FTP 上不起作用
【发布时间】:2013-11-22 19:27:40
【问题描述】:

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

我已经尝试过使用 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

【问题讨论】:

  • @K3rnel31 感谢文档,但对我来说有点不清楚(奇怪),那么这意味着什么事件仅由 DownloadFileAsync webclient 方法引发?我看到是的,它们是通过这种方法提出的,但这给我带来了两个问题。 1. 我不明白为什么只有异步才能引发这些事件。 2. 我在事件处理程序can't convert type 'System.ComponentModel.AsyncCompletedEventArgs' to type 'System.Net.DownloadDataCompletedEventArgs' 收到此错误。 PS:对不起我的英语。
  • 好的,我已经将方法签名更改为byval e as AsyncCompletedEventArgs,但是在引发下载事件时它会抛出“对象未设置引用”异常,这仍然没有解决。
  • @ElectroStudios 好的,等一下,让我帮你解决这个问题......
  • @K3rnel31 最后我可以处理异步下载,但我需要处理正常下载的过程,你能告诉我这是否可能或只能处理异步下载?跨度>

标签: .net vb.net ftp webclient


【解决方案1】:
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

结束类

【讨论】:

  • 不,这完全不正确,变量声明中的WithEvents 关键字让对象引发事件。
  • 是的,它允许对象引发事件,但是为了让您的处理程序订阅它们,您需要使用 addhandler 在运行时连接它。你为什么不试试呢?
  • 使用 withevents 您不再需要手动添加句柄。 Why don't you just try it? 你不应该假设的事情,我已经尝试过了(即使确定 addhandler 不是必需的),我已经尝试过了,但没有任何反应。还是谢谢
  • 为我工作。另请参阅 K3rnel31 的评论和链接。
  • 那么你能在你的答案中添加一个代码示例来测试它吗?它不适合我
【解决方案2】:

没有引发事件的唯一原因(如上面 cmets 中的@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 对象,因为单个 Web 客户端无法在尝试以异步方式下载的同时以异步方式上传,因此它应该抛出 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    相关资源
    最近更新 更多