为什么WPF中的UI控件具有线程亲和力?

时间:2012-01-04 20:08:47

标签: c# wpf

为什么创建控件的线程是可以更新它的线程?为什么没有MS让人们能够使用锁定和其他线程同步技术来读取和写入具有多个线程的UI控件上的属性。

2 个答案:

答案 0 :(得分:12)

每个MSDN的简短描述是

  

WPF的线程模型与现有的User32保持同步   具有线程亲和性的单线程执行的线程模型。该   主要原因是互操作性 - 像OLE 2.0这样的系统,   剪贴板和Internet Explorer都需要单线程   亲和力(STA)执行

更长的描述是:

  

WPF中的大多数对象派生自DispatcherObject,它提供了   用于处理并发和线程的基本构造。 WPF是   基于调度程序实现的消息传递系统。这有效   很像熟悉的Win32消息泵;实际上,WPF调度员   使用User32消息执行跨线程调用。

     

在讨论时,有两个核心概念需要理解   WPF中的并发性 - 调度程序和线程关联。

     

在WPF的设计阶段,目标是转向单一   执行线程,但是非线程“关联”模型。线   当组件使用执行的标识时,就会发生关联   线程存储某种类型的状态。最常见的形式是   使用线程本地存储(TLS)来存储状态。线程亲和力   要求每个逻辑执行线程只由一个拥有   操作系统中的物理线程,可以成为内存   密集。最后,WPF的线程模型与之保持同步   用于单线程执行的现有User32线程模型   线程亲和力。其主要原因是互操作性 -   OLE 2.0,剪贴板和Internet Explorer等系统都需要   单线程关联(STA)执行。

     

鉴于你有使用STA线程的对象,你需要一种方法   线程之间进行通信,并验证您是否正确   线。这就是调度员的角色。调度员是一个   基本的消息调度系统,具有多个优先级排队。   消息示例包括原始输入通知(鼠标移动),   框架函数(布局)或用户命令(执行此方法)。   通过派生DispatcherObject,您可以创建一个具有的CLR对象   STA行为,并将在创建时给出指向调度程序的指针   时间。

您可以阅读完整的文章here

我个人更喜欢WPF的单线程模型而不是必须使用锁定和线程同步技术。 Dispatcher可用于将消息传递到different priority levels的主UI线程,它负责大多数小型后台进程,如果您需要任何繁重的处理,那么您仍然可以创建自己的背景为此而奋斗。

答案 1 :(得分:3)

WPF,就像所有UI工具包一样,通过抽取消息循环来工作。由于消息可以随时出现并影响任何控制,因此您需要全局锁定。为了减少错误,您可能需要一个可以在锁定下调用委托的函数。也许是这样的:

Dispatcher.Invoke(Delegate, Object())

这被编组到UI线程而不是获取全局锁的事实只是一个实现细节。