0

我对silverlight 的busyindicator 控制有疑问。我有一个数据网格(datagrid1),其源设置为 wcf 服务(客户端)。当数据网格自行加载时,我想使用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
  • First point: Why are you using the ThreadPool?

Using a ThreadPool would be a good idea if your service was synchronous, but your WCF service is asynchronous: it won't block your UI thread after being called using Get_PosteSPTAsync.

  • Second point: there seems to be an issue with your IsBusy property. You're first setting it to true, then you starts an operation asynchronously, then you set it to false immediately. You should set it to false in the Completed handler.
  • Third point: the client_Get_PosteSPTCompleted handler won't be executed in the same thread as the UI thread (even if you don't use the ThreadPool). That's why you'll have to use the dispatcher here so force using the UI thread.

Your DataGrid1.ItemsSource = e.Result must be modified to:

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)

(note sure about the VB.Net syntax, but that's the idea)

  • Last point: I don't know about the client object lifetime, but you're adding a new handler to the Get_PosteSPTCompleted each time you call LoadGrid. Maybe you could think of detaching handlers after use.
于 2012-07-16T09:35:55.210 回答