2012-07-12 60 views
0

在Windows Phone 7中,我试图显示一些LINQ查询的状态。 我正在使用BackgroundWorker。我在调试窗口中看到进度更新,但在用户界面(TextBlock4.Text)中看不到进度更新。在所有查询结束后,进度似乎都会更新。此外,UI在运行查询时不响应。我如何避免UI冻结?我如何在UI中显示进度?是否有另一种显示查询进度的方法?BackgroundWorker UI不会更新Windows Phone 7的进度

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 

末级

回答

0

看起来你正在发行的工作将在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 
+0

如果我不使用调度的LINQ查询我得到一个错误:无效的跨线程访问。 – milo2011 2012-07-12 17:39:53

+0

我看到的所有LINQ都包装在Dispatcher.BeginInvoke中。我错过了什么吗? – 2012-07-12 17:55:12

+0

当我删除Dispatcher.BeginInvoke包装,我得到'无效的跨线程访问'错误。 – milo2011 2012-07-12 19:07:02