为什么要使用Dispatcher.BeginInvoke?

时间:2011-08-11 20:06:25

标签: silverlight dispatcher begininvoke

我已经看过(并阅读过)有关使用Dispatcher.BeginInvoke来确保UI线程上发生UI更新的信息。我理解这个推理。

但是我已经看到了一些示例,在视图代码中,分配属性(例如TextBlock的Text属性)只有在此Dispatcher.BeginInvoke中指定它时才被声明为安全。

问题 如果我从视图的代码隐藏中操作任何东西,是不是暗示它在UI线程上被操纵(假设我没有使用BackgroundWorker或异步服务调用)。

在上面提到的示例中,没有使用其他线程或异步操作。

问题2 如果我有一个异步Web服务处理程序,我想从此处理程序中更新TextBlock的字符串。我可以直接分配TB的Text属性,还是应该使用Dispatcher.BeginInvoke。请注意,我不会这样做,因为我喜欢数据绑定,而不是直接的UI元素操作。

2 个答案:

答案 0 :(得分:3)

你问“不是暗示它在UI线程上被操纵”。没有任何东西给出绝对保证,因为迈克指出非私有代码入口点可能在非UI线程上调用。

但是,您可以确定从UI元素到达的事件将在UI线程上。

至于采取任何预防措施以确保您的代码隐藏在UI线程上运行,我不认为这是明智的。如果您只是让代码正常进行会发生什么。可能它成功,因为你实际上没有与UI元素交互,没有伤害。或者代码继续并抛出异常。那不好吗?

使用预防性BeginInvoke会导致调用代码与调用的UI操作代码异步完成。这可能具有不可预测的结果,这可能是追踪的噩梦。让代码表现出可预测性要好得多。只需在应该负责在正确的线程上调用UI组件的代码中抛出一个错误。所有代码隐藏都作为UI组件的一部分运行,例如UserControlPage

还要考虑运行时,SDK和工具包中的现有UI元素不会进行预防性的线程切换。

编辑:回答第二个问题的厚颜无耻的添加

这取决于您使用的Async API以及调用API的线程。

当您从UI线程调用WebClient异步方法时,也会在UI线程上引发相应的事件。类似地,如果您正在使用WCF服务Client类,则如果最初在UI线程上调用异步操作,则将在UI线程上引发Completed事件。

但是,当在WebRequest组件(或WCF的标准服务接口)上使用Begin / End对时,无论用于启动操作的原始线程如何,回调都将在后台线程上运行。

答案 1 :(得分:0)

如果它是仅响应UI事件的受保护方法或事件处理程序,那么在没有调度程序的情况下您应该是安全的。但是,如果您的代码可以以任何方式在外部公开,那么最好不要对它可能执行的线程做任何假设。

相关问题