14

在 C# 中开发时,我多次遇到过这个问题。我会愉快地编码,在线程之间来回传递对象等等,然后突然之间我得到了这个熟悉的错误:

“调用线程无法访问此对象,因为不同的线程拥有它。”

好吧,我以前处理过它,尤其是 GUI 线程上的对象。您只需要编写一些额外的代码来围绕该特定问题进行编程。但是每隔一段时间我就会遇到一个很普通的对象,但它不喜欢被不同的线程访问。

编辑我在原来的帖子中弄错了导致访问异常的对象。它不是IPAddress,而是它的System.Printing.PrintQueue。我用来获取IP地址的。这是您无法从超过 1 个线程中评估的对象。

我写的所有课程都没有这个问题。我什至不知道我自己会如何实现它。您是否必须使用创建您的线程 ID 保留一个成员变量,然后在每个属性和方法访问时检查当前线程与该变量是否一致?这似乎很疯狂。为什么微软会决定......“好吧...... PrintQueue,绝对不能在线程之间共享。但是这些其他类......它们很好。”

为什么某些对象被多线程访问阻止?

4

1 回答 1

3

我认为这可以很好地解释事情,我认为这与 COM 密切相关。

http://msdn.microsoft.com/en-us/library/ms693344%28v=vs.85%29

具体来说。

通常,查看 COM 线程体系结构的最简单方法是将进程中的所有 COM 对象视为划分为称为单元的组。一个 COM 对象恰好存在于一个单元中,从某种意义上说,它的方法只能由属于该单元的线程合法地直接调用。任何其他想要调用该对象的线程都必须通过代理。

有两种类型的公寓:单线程公寓和多线程公寓。

单线程单元只包含一个线程,因此所有存在于单线程单元中的 COM 对象只能从属于该单元的一个线程接收方法调用。对单线程单元中的 COM 对象的所有方法调用都与单线程单元线程的 Windows 消息队列同步。具有单个执行线程的进程只是该模型的一个特例。

多线程单元由一个或多个线程组成,因此位于多线程单元中的所有 COM 对象都可以直接从属于多线程单元的任何线程接收方法调用。多线程单元中的线程使用称为自由线程的模型。对多线程单元中的 COM 对象的调用由对象本身同步。

于 2012-07-03T19:15:47.683 回答