VB.NET下载器下载后切换单选按钮触发空引用异常问题
问题分析与解决方案
错误原因
你遇到的空引用错误,根源在下载完成后的清理代码中:
在httpClient_DownloadProgressChanged方法里,你错误地执行了txtLocation = Nothing和txtFilename = Nothing——这是把控件对象本身设置为null,而不是清空控件的文本内容。当后续切换单选按钮触发CheckedChanged事件时,代码尝试访问txtFilename.Text,但此时txtFilename已经是不存在的对象,自然抛出空引用异常。
另外还有一个潜在问题:用ProgressBar1.Value = 100来判断下载完成并不严谨,因为DownloadProgressChanged事件触发到100%时,异步下载操作可能还未完全结束,正确的做法是通过DownloadFileCompleted事件处理下载完成后的逻辑。
修复步骤
- 修正控件清空逻辑:将赋值控件对象为
Nothing的代码,改为清空控件的Text属性。 - 改用
DownloadFileCompleted事件处理完成逻辑:把下载完成后的清理、提示逻辑移到这个事件里,确保下载操作真正完成后再执行清理。 - 移除
ProgressChanged中的完成判断代码:避免提前执行清理操作导致的问题。
修改后的完整代码
Option Explicit On Option Strict On Imports System.Net Public Class Form1 Private WithEvents httpClient As WebClient Dim UserName As String Dim Password As String Dim USER As String = Environment.UserName Dim SAVE As String Dim Filename As String Dim Destination As String Dim URL As String Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click UserName = txtUserName.Text Password = txtPassword.Text URL = txtURL.Text Destination = txtLocation.Text Filename = txtFilename.Text SAVE = "C:\Users\" & USER & "\Desktop\" & txtName.Text & "\" & Destination & "\" & Filename httpClient = New WebClient Try httpClient.Credentials = New NetworkCredential(UserName, Password) httpClient.DownloadFileAsync(New Uri(URL), SAVE) Catch ex As Exception MessageBox.Show(ex.Message, "Critical") End Try End Sub Private Sub httpClient_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles httpClient.DownloadProgressChanged ProgressBar1.Value = e.ProgressPercentage Label6.Text = CInt(e.BytesReceived / 1048576) & " MB" End Sub Private Sub httpClient_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles httpClient.DownloadFileCompleted ' 处理下载完成(包括成功或失败) If e.Error Is Nothing Then MessageBox.Show(Filename & " has been successfully downloaded!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information) ' 清空控件文本,而非控件对象 Label6.Text = Nothing txtURL.Text = Nothing txtLocation.Text = Nothing txtFilename.Text = Nothing ProgressBar1.Value = 0 ' 取消单选按钮选中状态 rdoAVI.Checked = False rdoMP4.Checked = False rdoMKV.Checked = False Else MessageBox.Show("Download failed: " & e.Error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End If ' 释放WebClient资源 httpClient.Dispose() httpClient = Nothing ' 可选,避免后续误访问 End Sub Private Sub rdoAVI_CheckedChanged(sender As Object, e As EventArgs) Handles rdoAVI.CheckedChanged If rdoAVI.Checked = True Then txtFilename.Text = txtName.Text & " S" & txtSeason.Text & " E" & txtEpisode.Text & ".avi" End If End Sub Private Sub rdoMP4_CheckedChanged(sender As Object, e As EventArgs) Handles rdoMP4.CheckedChanged If rdoMP4.Checked = True Then txtFilename.Text = txtName.Text & " S" & txtSeason.Text & " E" & txtEpisode.Text & ".mp4" End If End Sub Private Sub rdoMKV_CheckedChanged(sender As Object, e As EventArgs) Handles rdoMKV.CheckedChanged If rdoMKV.Checked = True Then txtFilename.Text = txtName.Text & " S" & txtSeason.Text & " E" & txtEpisode.Text & ".mkv" End If End Sub End Class
额外说明
- 改用
DownloadFileCompleted事件可以准确捕获下载完成的时机,同时还能处理下载过程中出现的异常(比如网络中断、文件无法写入等)。 - 清空控件时始终操作
Text属性,而不是控件对象本身,这是WinForms开发中的基础规范,避免控件对象被意外销毁导致后续操作报错。
内容的提问来源于stack exchange,提问作者Wilko84
相关产品推荐
相关产品推荐

