4

我已经看到(并阅读)关于使用 Dispatcher.BeginInvoke 来确保 UI 更新发生在 UI 线程上。我明白这个道理。

但是我看到了在视图代码隐藏中分配属性(例如 TextBlock 的 Text 属性)的示例,仅当您在此 Dispatcher.BeginInvoke 中分配它时才被声明为安全的。

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

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

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

4

2 回答 2

3

您问“是否暗示它正在 UI 线程上被操纵”。没有任何东西可以提供绝对的保证,因为 Mike 指出非私有代码入口点可能会在非 UI 线程上调用。

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

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

使用预防措施BeginInvoke会导致调用代码与被调用的 UI 操作代码异步完成。这可能会产生无法预测的结果,这可能是追踪的噩梦。让您的代码行为可预测要好得多。只需将错误返回到应该负责在正确线程上调用 UI 组件的代码。毕竟代码隐藏是作为 UI 组件的一部分运行的,例如 aUserControl或 a Page

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

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

这取决于您使用的异步 API 以及调用该 API 的线程。

当您从 UI 线程调用WebClient异步方法时,也会在 UI 线程上引发相应的事件。同样,如果您使用的是 WCF 服务客户端类,并且最初在 UI 线程上调用异步操作,则会在 UI 线程上引发 Completed 事件。

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

于 2011-08-11T21:36:45.080 回答
0

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

于 2011-08-11T20:13:45.780 回答