新手:使用busyindicator无效的跨线程访问(silverlight和wcf服务)

时间:2012-07-16 08:55:55

标签: wcf silverlight multithreading busyindicator

我遇到了对silverlight的busyindicator控件的问题。 我有一个datagrid(datagrid1),其源设置为wcf服务(客户端)。 当datagrid加载自己时,我想使用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

我知道“新线程”中不存在datagrid控件,但是我必须如何避免此错误?

谢谢。

威廉

1 个答案:

答案 0 :(得分:1)

  • 第一点:您为什么使用ThreadPool

如果您的服务是同步的,那么使用ThreadPool将是一个好主意,但您的WCF服务是异步的:它在使用Get_PosteSPTAsync调用后不会阻止您的UI线程。

  • 第二点:您的IsBusy财产似乎存在问题。您首先将其设置为true,然后异步启动操作,然后立即将其设置为false。您应该在Completed处理程序中将其设置为false。
  • 第三点: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_PosteSPTCompleted时,您都会向LoadGrid添加新的处理程序。也许您可以考虑在使用后分离处理程序。