我想知道为什么这段代码不起作用,它不会抛出任何异常,文件被下载,只是事件不是。
我已尝试使用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
答案 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