2012-07-12 42 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