BackgroundWorkers - 用于静态进度的ProgressChanged

时间:2015-01-28 10:50:57

标签: vb.net multithreading backgroundworker

我想使用backgroundworker非常频繁地轮询硬件传感器,而不会让我的UI无法运行。 因为后台工作人员只是轮询直到被打断 - 运行时完全是由用户打断它所决定的 - 它的进展没有变化可以这么说。

如果我使用常量值调用ReportProgress,例如ReportProgress(1),这仍然会调用ProgressChanged吗?我要求ProgressChanged根据最新的民意调查数据更新UI。

1 个答案:

答案 0 :(得分:1)

作为第一个参数传递给ReportProgress的值仅用于UI线程上的代码,以显示后台任务的进度。
它对执行对ProgressChanged的调用并不重要。

如果需要将一些不同的数据传递给ProgressChanged事件,可以使用带有两个参数的ReportProgress重载,并允许将自定义对象的实例作为第二个参数传递。

在这个非常简单的例子中,我定义了一个名为WorkingStatus的类,只有一个属性我在DoWork方法中更改,然后我将此类的实例传递给ProgressChanged事件。当然,你想要在UI线程上显示的所有信息,你的WorkingStatus类可能会更复杂

public class WorkingStatus

    public Current as Integer
    '.... other properties as needed....
End Class

Sub Main
    Dim bkw = new BackgroundWorker()
    bkw.WorkerReportsProgress = true
    AddHandler bkw.ProgressChanged, AddressOf bgw_ProgressChanged
    AddHandler bkw.DoWork, AddressOf bgw_DoWork
    bkw.RunWorkerAsync()

    ' This loop just to avoid the immediate close of the example
    Dim counter = 0
    While (bkw.IsBusy)
        counter+=1
        Console.WriteLine("IsBusy " & counter.ToString())
        Thread.Sleep(150)
    End While     
End Sub




private sub bgw_DoWork(sender as object, e as DoWorkEventArgs)
    Dim bgw = DirectCast(sender, BackgroundWorker)
    Dim sts = new WorkingStatus() With {.Current = 0}

    '  A simulation of your inner working 
    for i = 0 to 10
        Thread.Sleep(5000)
        sts.Current+=1
        bgw.ReportProgress(1, sts)
    Next
    Console.WriteLine("Background DoWork ENDED")
End Sub

private sub bgw_ProgressChanged(sender as object, e as ProgressChangedEventArgs)

    Dim sts = DirectCast(e.UserState, WorkingStatus)
    Console.WriteLine("Progress:" & e.ProgressPercentage.ToString() & ", Status=" & sts.Current)
End Sub