Question

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

Was it helpful?

Solution

  • 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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top