0

Silverlightのbusyindicatorコントロールに問題があります。ソースがwcfサービス(クライアント)に設定されたdatagrid(datagrid1)があります。データグリッドがそれ自体をロードするときに、silvelrightツールキットのbusyindicatorコントロール(bi)を使用したいと思います。

しかし、「ThreadPool」を使用すると、「無効なクロススレッドアクセス」が発生します。

Sub LoadGrid()
        Dim caisse As Integer = ddl_caisse.SelectedValue
        Dim env As Integer = ddl_env.SelectedValue

        bi.IsBusy = True
        ThreadPool.QueueUserWorkItem(Sub(state)
                                         AddHandler client.Get_PosteSPTCompleted, AddressOf client_Get_PosteSPTCompleted
                                         client.Get_PosteSPTAsync(caisse, env)
                                         Dispatcher.BeginInvoke(Sub()
                                                                    bi.IsBusy = False
                                                                End Sub)
                                     End Sub)
End Sub

Private Sub client_Get_PosteSPTCompleted(sender As Object, e As ServiceReference1.Get_PosteSPTCompletedEventArgs)
    DataGrid1.ItemsSource = e.Result ' Here, Invalid cross thread access
End Sub

データグリッドコントロールが「新しいスレッド」に存在しないことは知っていますが、このエラーを回避するにはどうすればよいですか?

ありがとうございました。

ウィリアム

4

1 に答える 1

1
  • 最初のポイント:なぜあなたは?を使用しているのThreadPoolですか?

サービスが同期している場合はaを使用するThreadPoolことをお勧めしますが、WCFサービスは非同期です。を使用して呼び出された後、UIスレッドをブロックしませんGet_PosteSPTAsync

  • 2番目のポイント:あなたのIsBusy財産に問題があるようです。最初にに設定しtrue、次に非同期で操作を開始し、次にfalseすぐにに設定します。Completedハンドラーでfalseに設定する必要があります。
  • 3番目のポイント:client_Get_PosteSPTCompletedハンドラーは、UIスレッドと同じスレッドで実行されません(を使用しない場合でもThreadPool)。そのため、ここではディスパッチャを使用する必要があるため、UIスレッドを強制的に使用してください。

次のDataGrid1.ItemsSource = e.Resultように変更する必要があります。

Dispatcher.BeginInvoke(Sub()
    DataGrid1.ItemsSource = e.Result     ' Fixes the UI thread issue
    bi.IsBusy = False     ' Sets busy as false AFTER completion (see point 2)
End Sub)

(VB.Net構文については注意してください。ただし、それがアイデアです)

  • 最後のポイント:オブジェクトの存続期間についてはわかりませんが、を呼び出すたびclientに新しいハンドラーを追加しています。たぶん、使用後にハンドラーを切り離すことを考えることができます。Get_PosteSPTCompletedLoadGrid
于 2012-07-16T09:35:55.210 に答える