问题
I have a problem with the busyindicator control of silverlight. I have a datagrid (datagrid1) with its source set to a wcf service (client). I would like to use the busyindicator control (bi) of silvelright toolkit when the datagrid loads itself.
But I have an "Invalid cross thread access" when I use "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
I know that the datagrid control doesn't exist in the "new thread", but how have to I make to avoid this error?
Thank you.
William
回答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 totrue
, then you starts an operation asynchronously, then you set it tofalse
immediately. You should set it to false in theCompleted
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 theThreadPool
). 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 theGet_PosteSPTCompleted
each time you callLoadGrid
. Maybe you could think of detaching handlers after use.
来源:https://stackoverflow.com/questions/11500957/newbie-invalid-cross-thread-access-with-using-busyindicator-silverlight-and-wc