如何正确退出已取消的 BackgroundWorker 异步?
How to properly exit from canceled BackgroundWorker async?
我目前正在使用此代码(可以正常工作),但我对它的外观不满意...是否有更专业的方法?
这是我现在使用的代码:
Private Sub BackgroundWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork
Try
If BackgroundWorker.CancellationPending Then
e.Cancel = True
Exit Sub
End If
LatestVersion = Web.DownloadString(UpdateLink)
If BackgroundWorker.CancellationPending Then
e.Cancel = True
Exit Sub
End If
If LatestVersion.Contains(InstalledVersion) Then
e.Result = UP_TO_DATE
Else
e.Result = OUTDATED
End If
Web.Dispose()
Catch ex As Exception
e.Result = ex.Message
End Try
End Sub
如您所见,我将相同的条件重复了两次。但是想象一下,如果有更多的代码,我应该重复更多次...
我的问题是我想随时退出 Sub,只要 BackgroundWorker.CancellationPending
属性 设置为 True
。
我使用相同的条件两次,因为我想检查操作是否在下载我的字符串之前和之后被取消(我不想等待字符串被下载,而我已经取消了操作...这是浪费时间)。
我应该使用 While
语句吗?如果是,如何?
不要使用 BackgroundWorker
,这个问题就会消失。代码可能应该是(VB 和 C# 的混合):
//Instance field:
CancellationTokenSource cts = ...;
//Update method
var downloadTask = HttpClient().DownloadString(UpdateLink, cts.Token);
await Task.WhenAll(downloadTask, cts.Token); //Wait with timeout
LatestVersion = await downloadTask;
If LatestVersion.Contains(InstalledVersion) Then
ShowResult(UP_TO_DATE);
Else
ShowResult(OUTDATED);
End If
如果您想取消,请发出信号 cts
。
此外,缺少错误处理。这很容易测试和添加。
我找到了另一个解决方案。顺便说一句,我已将 Web
重命名为 WebClient
...
这是我的代码:
Private Sub Form1_Load() Handles Form1.Load
AddHandler WebClient.DownloadStringCompleted, AddressOf WebClient_DownloadStringCompleted
End Sub
Private Sub BackgroundWorker_DoWork() Handles BackgroundWorker.DoWork
WebClient.DownloadStringAsync(New Uri(UpdateLink))
End Sub
Private Sub WebClient_DownloadStringCompleted(sender As Object, e As System.Net.DownloadStringCompletedEventArgs)
Dim Output As String = Nothing
If Not e.Cancelled Then
LatestVersion = e.Result
If LatestVersion.Contains(InstalledVersion) Then
Output = UP_TO_DATE
Else
Output = OUTDATED
End If
End If
End Sub
而且,要取消操作,我 运行 WebClient.CancelAsync()
。
我目前正在使用此代码(可以正常工作),但我对它的外观不满意...是否有更专业的方法?
这是我现在使用的代码:
Private Sub BackgroundWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork
Try
If BackgroundWorker.CancellationPending Then
e.Cancel = True
Exit Sub
End If
LatestVersion = Web.DownloadString(UpdateLink)
If BackgroundWorker.CancellationPending Then
e.Cancel = True
Exit Sub
End If
If LatestVersion.Contains(InstalledVersion) Then
e.Result = UP_TO_DATE
Else
e.Result = OUTDATED
End If
Web.Dispose()
Catch ex As Exception
e.Result = ex.Message
End Try
End Sub
如您所见,我将相同的条件重复了两次。但是想象一下,如果有更多的代码,我应该重复更多次...
我的问题是我想随时退出 Sub,只要 BackgroundWorker.CancellationPending
属性 设置为 True
。
我使用相同的条件两次,因为我想检查操作是否在下载我的字符串之前和之后被取消(我不想等待字符串被下载,而我已经取消了操作...这是浪费时间)。
我应该使用 While
语句吗?如果是,如何?
不要使用 BackgroundWorker
,这个问题就会消失。代码可能应该是(VB 和 C# 的混合):
//Instance field:
CancellationTokenSource cts = ...;
//Update method
var downloadTask = HttpClient().DownloadString(UpdateLink, cts.Token);
await Task.WhenAll(downloadTask, cts.Token); //Wait with timeout
LatestVersion = await downloadTask;
If LatestVersion.Contains(InstalledVersion) Then
ShowResult(UP_TO_DATE);
Else
ShowResult(OUTDATED);
End If
如果您想取消,请发出信号 cts
。
此外,缺少错误处理。这很容易测试和添加。
我找到了另一个解决方案。顺便说一句,我已将 Web
重命名为 WebClient
...
这是我的代码:
Private Sub Form1_Load() Handles Form1.Load
AddHandler WebClient.DownloadStringCompleted, AddressOf WebClient_DownloadStringCompleted
End Sub
Private Sub BackgroundWorker_DoWork() Handles BackgroundWorker.DoWork
WebClient.DownloadStringAsync(New Uri(UpdateLink))
End Sub
Private Sub WebClient_DownloadStringCompleted(sender As Object, e As System.Net.DownloadStringCompletedEventArgs)
Dim Output As String = Nothing
If Not e.Cancelled Then
LatestVersion = e.Result
If LatestVersion.Contains(InstalledVersion) Then
Output = UP_TO_DATE
Else
Output = OUTDATED
End If
End If
End Sub
而且,要取消操作,我 运行 WebClient.CancelAsync()
。