如何正确退出已取消的BackgroundWorker异步?

时间:2015-08-23 17:05:00

标签: vb.net backgroundworker cancellation

我目前正在使用这个代码(这是有效的),但我对它的外观并不满意......有没有更专业的方法呢?

这是我现在使用的代码:

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声明吗?如果是,怎么样?

2 个答案:

答案 0 :(得分:2)

不要使用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

此外,缺少错误处理。这很容易测试和添加。

答案 1 :(得分:0)

我找到了另一个解决方案。顺便说一句,我已经 <GridView Grid.Row="1" x:Name="gridView" SelectionChanged="gridView_SelectionChanged" ItemsSource="{Binding}" SelectionMode="None" IsItemClickEnabled="True" ItemClick="gridView_ItemClick"> <GridView.ItemTemplate> <DataTemplate> <Border Background="Black"> <Image x:Name="ima" Height="120" Stretch="UniformToFill"> <Image.Source> <BitmapImage x:Name="bm" UriSource="{Binding Pa}" ImageOpened="bm_ImageOpened"/> </Image.Source> </Image> </Border> </DataTemplate> </GridView.ItemTemplate> <GridView.ItemsPanel> <ItemsPanelTemplate> <VariableSizedWrapGrid Orientation="Vertical" VerticalChildrenAlignment="Stretch"/> </ItemsPanelTemplate> </GridView.ItemsPanel> </GridView> ...

重命名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