新手:使用busyindicator无效的跨线程访问(silverlight和wcf服务) [英] Newbie: Invalid cross thread access with using busyindicator (silverlight and wcf service)
问题描述
我对silverlight的busyindicator控制有问题. 我有一个datagrid(datagrid1),其源设置为wcf服务(客户端). 当数据网格加载自身时,我想使用silvelright工具包的busyindicator控件(bi).
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.
但是当我使用"ThreadPool"时,我有一个无效的跨线程访问".
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
我知道datagrid控件在新线程"中不存在,但是如何避免该错误?
I know that the datagrid control doesn't exist in the "new thread", but how have to I make to avoid this error?
谢谢.
威廉
推荐答案
- 第一点:为什么要使用
ThreadPool
? - First point: Why are you using the
ThreadPool
? - 第二点:您的
IsBusy
属性似乎有问题.首先将其设置为true
,然后异步启动操作,然后立即将其设置为false
.您应该在Completed
处理程序中将其设置为false. - 第三点:
client_Get_PosteSPTCompleted
处理程序将不会在与UI线程相同的线程中执行(即使您不使用ThreadPool
).这就是为什么您必须在此处使用调度程序,因此强制使用UI线程的原因. - 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.
如果您的服务是同步的,则使用ThreadPool
是个好主意,但是您的WCF服务是异步的:使用Get_PosteSPTAsync
调用后,它不会阻塞UI线程.
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
.
您的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语法的信息,但这就是想法)
(note sure about the VB.Net syntax, but that's the idea)
- 最后一点:我不知道
client
对象的生命周期,但是每次调用LoadGrid
时,您都会向Get_PosteSPTCompleted
添加新的处理程序.也许您会想到使用后分离处理程序.
- 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.
这篇关于新手:使用busyindicator无效的跨线程访问(silverlight和wcf服务)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!