0

Windows Phone 7 で、いくつかの LINQ クエリのステータスを表示しようとしています。私はバックグラウンドワーカーを使用しています。デバッグ ウィンドウでは進行状況の更新が表示されますが、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

クラス終了

4

1 に答える 1

0

UIスレッドで実行する作業を発行しているようです。DoWork メソッドは Dispatcher を呼び出すべきではありません。これにより、すべての作業が BackgroundWorker スレッドではなく UI スレッドに置かれます。

更新:メンバー変数にアクセスしていることに気付きました。これを行うことはお勧めしません。バックグラウンド ワーカーは計算した結果を返す必要があります。リストで返される結果を示す簡単な例を次に示します (私は 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
于 2012-07-12T17:37:43.053 に答える