Windows phone 7 BackgroundWorker用户界面没有';t更新Windows Phone 7中的进度

Windows phone 7 BackgroundWorker用户界面没有';t更新Windows Phone 7中的进度,windows-phone-7,backgroundworker,Windows Phone 7,Backgroundworker,在WindowsPhone7中,我试图显示一些LINQ查询的状态。 我在用BackgroundWorker。我在调试窗口中看到进度更新,但在UI(TextBlock4.Text)中看不到。所有查询结束后,进度似乎会更新。此外,UI在运行查询时没有响应。如何避免UI冻结?如何在UI中显示进度?是否有其他方式显示查询进度 Partial Public Class pagInvoicesReport Inherits PhoneApplicationPage Private WithEvents m

在WindowsPhone7中,我试图显示一些LINQ查询的状态。 我在用BackgroundWorker。我在调试窗口中看到进度更新,但在UI(TextBlock4.Text)中看不到。所有查询结束后,进度似乎会更新。此外,UI在运行查询时没有响应。如何避免UI冻结?如何在UI中显示进度?是否有其他方式显示查询进度

Partial Public Class pagInvoicesReport
Inherits PhoneApplicationPage

Private WithEvents mWorker As New BackgroundWorker()

Private nJan As Nullable(Of Decimal) = 0
Private nFeb As Nullable(Of Decimal) = 0
Private nMar As Nullable(Of Decimal) = 0
Private nApr As Nullable(Of Decimal) = 0
Private nMay As Nullable(Of Decimal) = 0
Private nJun As Nullable(Of Decimal) = 0
Private nJul As Nullable(Of Decimal) = 0
Private nAug As Nullable(Of Decimal) = 0
Private nSept As Nullable(Of Decimal) = 0
Private nOct As Nullable(Of Decimal) = 0
Private nNov As Nullable(Of Decimal) = 0
Private nDec As Nullable(Of Decimal) = 0

Public Sub New()
    InitializeComponent()
    mWorker.WorkerReportsProgress = True
End Sub

Private Sub startButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles startButton.Click
    mWorker.RunWorkerAsync()
End Sub

Private Sub mWorker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles mWorker_ProgressChanged
    TextBlock4.Text = e.ProgressPercentage.ToString() & "%"
    System.Diagnostics.Debug.WriteLine(e.ProgressPercentage.ToString() & "%")
End Sub

Private Sub GetGraphValues() Handles mWorker.DoWork
    System.Windows.Deployment.Current.Dispatcher.BeginInvoke( _
            Sub()
                Using theDB As New appContext("Data Source=isostore:/theDB.sdf")
                    Try
                        If (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 1 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?))) IsNot Nothing Then
                            nJan = (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 1 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?)))
                        Else
                            nJan = 0
                        End If
                    Catch ex As Exception
                        MessageBox.Show("There was an error!" & vbCrLf & ex.Message, "Error!", MessageBoxButton.OK)
                    End Try
                End Using
            End Sub)

    mWorker.ReportProgress(8)

    System.Windows.Deployment.Current.Dispatcher.BeginInvoke( _
        Sub()
            Using theDB As New appContext("Data Source=isostore:/theDB.sdf")
                Try
                    If (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 2 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?))) IsNot Nothing Then
                        nFeb = (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 2 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?)))
                    Else
                        nFeb = 0
                    End If
                Catch ex As Exception
                    MessageBox.Show("There was an error!" & vbCrLf & ex.Message, "Error!", MessageBoxButton.OK)
                End Try
            End Using
        End Sub)

    mWorker.ReportProgress(17)



    System.Windows.Deployment.Current.Dispatcher.BeginInvoke( _
        Sub()
            Using theDB As New appContext("Data Source=isostore:/theDB.sdf")
                Try
                    If (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 12 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?))) IsNot Nothing Then
                        nDec = (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 12 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?)))
                    Else
                        nDec = 0
                    End If
                Catch ex As Exception
                    MessageBox.Show("There was an error!" & vbCrLf & ex.Message, "Error!", MessageBoxButton.OK)
                End Try
            End Using
        End Sub)
    mWorker.ReportProgress(100)
End Sub

End Class

看起来您正在发布要在UI线程上完成的工作。您认为DoWork方法不应调用调度程序。这将把所有的工作放在UI线程而不是BackgroundWorker线程上

更新:刚刚注意到您正在访问成员变量。不建议这样做,您的后台工作人员应该返回其计算的结果,下面是一个简单的示例,显示在列表中返回的结果(我不是VB专家,请耐心等待)。工作程序完成后,获取结果并替换属性

尝试将您的DoWork处理程序更改为:

Private Sub GetGraphValues(args as DoWorkEventArgs) Handles mWorker.DoWork
    Dim list as List<Decimal>();
    Dim jan as Decimal
    Dim feb as Decimal
    Dim dec as Dicimal
    Using theDB As New appContext("Data Source=isostore:/theDB.sdf")
        Try
            If (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 1 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?))) IsNot Nothing Then
                jan = (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 1 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?)))
            Else
                jan = 0
            End If
        Catch ex As Exception
            ' Showing messageBox SHOULD be shown on UI thread
            System.Windows.Deployment.Current.Dispatcher.BeginInvoke( _
            Sub()
                MessageBox.Show("There was an error!" & vbCrLf & ex.Message, "Error!", MessageBoxButton.OK)
            End Sub)
        End Try
    End Using
    list.Add(jan);

    mWorker.ReportProgress(8)

    Using theDB As New appContext("Data Source=isostore:/theDB.sdf")
        Try
            If (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 2 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?))) IsNot Nothing Then
                feb = (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 2 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?)))
            Else
                feb = 0
            End If
        Catch ex As Exception
            ' Showing messageBox SHOULD be shown on UI thread
            System.Windows.Deployment.Current.Dispatcher.BeginInvoke( _
            Sub()
                MessageBox.Show("There was an error!" & vbCrLf & ex.Message, "Error!", MessageBoxButton.OK)
            End Sub)
        End Try
    End Using
    list.Add(feb)

    mWorker.ReportProgress(17)

    Using theDB As New appContext("Data Source=isostore:/theDB.sdf")
        Try
            If (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 12 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?))) IsNot Nothing Then
                dec = (Aggregate r In theDB.InvoicesRecords Where r.InvoiceDateTime.Month = 12 And r.InvoiceDateTime.Year = 2012 And r.MainID = 1 Into Sum(CType(r.Cost, Decimal?)))
            Else
                dec = 0
            End If
        Catch ex As Exception
            ' Showing messageBox SHOULD be shown on UI thread
            System.Windows.Deployment.Current.Dispatcher.BeginInvoke( _
            Sub()
                MessageBox.Show("There was an error!" & vbCrLf & ex.Message, "Error!", MessageBoxButton.OK)
            End Sub)
        End Try
    End Using
    list.Add(dec)

    mWorker.ReportProgress(100)
    args.Result = list
End Sub
Private子GetGraphValue(作为DoWorkEventArgs的参数)处理mWorker.DoWork
将列表设置为列表();
十进制
十进制
Dim dec as Dicimal
将DB用作新的appContext(“数据源=isostore:/theDB.sdf”)
尝试
如果(r.InvoiceDateTime.Month=1,r.InvoiceDateTime.Year=2012,r.MainID=1的DB.InvoicesRecords中的r合计为总和(CType(r.Cost,Decimal?)不是零,则
jan=(将b.Invoices记录中的r相加,其中r.InvoicesDateTime.Month=1,r.InvoicesDateTime.Year=2012,r.MainID=1,并将其相加(C类型(r.Cost,十进制?))
其他的
1月=0
如果结束
特例
'显示消息框应显示在UI线程上
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(_
分()
Show(“出现错误!”&vbCrLf&ex.Message,“error!”,MessageBoxButton.OK)
末端接头)
结束尝试
终端使用
增加(1月);
mWorker.ReportProgress(8)
将DB用作新的appContext(“数据源=isostore:/theDB.sdf”)
尝试
如果(b.invoices记录中的合计r,其中r.invoicesdatetime.Month=2,r.invoicesdatetime.Year=2012,r.MainID=1)的总和(CType(r.Cost,Decimal?)不是零,则
feb=(将b.invoices记录中的r相加,其中r.invoicesdatetime.Month=2,r.invoicesdatetime.Year=2012,r.MainID=1,并将其相加(CType(r.Cost,Decimal?))
其他的
二月=0
如果结束
特例
'显示消息框应显示在UI线程上
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(_
分()
Show(“出现错误!”&vbCrLf&ex.Message,“error!”,MessageBoxButton.OK)
末端接头)
结束尝试
终端使用
列表。添加(2月)
mWorker.报告进度(17)
将DB用作新的appContext(“数据源=isostore:/theDB.sdf”)
尝试
如果(r.InvoiceDateTime.Month=12,r.InvoiceDateTime.Year=2012,r.MainID=1的B.InvoicesRecords中的合计r为总和(CType(r.Cost,Decimal?)不是零,则
dec=(将b.InvoicesRecords中的r相加,其中r.InvoicesDateTime.Month=12,r.InvoicesDateTime.Year=2012,r.MainID=1,并将其相加(C类型(r.Cost,十进制?))
其他的
十二月=0
如果结束
特例
'显示消息框应显示在UI线程上
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(_
分()
Show(“出现错误!”&vbCrLf&ex.Message,“error!”,MessageBoxButton.OK)
末端接头)
结束尝试
终端使用
列表。添加(12月)
mWorker.报告进度(100)
args.Result=list
端接头

如果我没有为LINQ查询使用Dispatcher,我会收到一个错误:无效的跨线程访问。我看到的所有LINQ都包装在Dispatcher.BeginInvoke中。我是否遗漏了什么?当我删除Dispatcher.BeginInvoke包装时,会出现“无效的跨线程访问”错误。我是否应该在mWorker\u ProgressChanged sub中使用Dispatcher.BeginInvoke?您不必这样做。它应该在UI线程上启动,但也不会造成伤害。只是不要从后台工作线程调用UI线程上的工作。查看我对答案的更改