gpt4 book ai didi

.NET 框架 : Are objects apartment bound?

转载 作者:行者123 更新时间:2023-12-04 11:46:24 24 4
gpt4 key购买 nike

给定:从一个线程构造 ADO Connection 对象并将其提供给另一个线程是 禁止 .这两个线程是不同的公寓,即使第一个线程将 从不再次触摸它(甚至不保持对它的引用!),没关系。

那个 ADO Connection 对象是由 ThreadA 创建的,ThreadA 是唯一的线程,在任何情况下,在任何情况下,都永远被允许使用该 Connection 对象,永远。

现在将“ADO 连接”替换为“ADO.NET 连接”。是否适用相同的规则?

我知道 .NET 框架中的大多数对象都不是线程安全的。例如,DictionaryEntry SDK中的结构说:

Thread Safety
Any public static members of this type are thread safe. Any instance members are not guaranteed to be thread safe.



我明白 不是线程安全的意味着如果我要从不同的线程访问它,我必须同步对对象的访问。这一切都很好,我可以确保一次只有一个线程访问该对象:
lock (myObject)
{
...
}

但是还有一些东西不仅仅是线程安全的。

在 COM 中,(某些)对象被绑定(bind)到创建它的“公寓”。一旦对象在一间公寓上建成,您就是 禁止从另一个公寓访问它 - 无论您如何保护该对象免受多个同时线程访问。

.NET 中是否存在类似的概念?

更多信息

我知道你被禁止从创建它的线程以外的线程访问控件——即使你以线程安全的方式使用它。这在 MSDN 上没有记录:

Thread Safety

Only the following members are thread safe: BeginInvoke, EndInvoke, Invoke, InvokeRequired, and CreateGraphics if the handle for the control has already been created. Calling CreateGraphics before the control's handle has been created on a background thread can cause illegal cross thread calls.



当您从单个线程创建和使用控件时,没有提到控件引发异常 - 当该线程不是应用程序启动时创建的第一个线程时。

但是任意对象呢?关于什么:
public class MyClass
{
int _number;

public int Number { get { return _number; } set { _number = value; } }
}

MyClass myObject = new MyClass();

只要我同步对 myObject 的访问,两个线程就可以与之交谈吗?

这同样适用于:
List<Object> sharedList = new List<Object>();

两个线程可以与列表对话,只要它们不同时进行,通常使用:
lock (sharedList)
{
sharedList.Add(data);
}

允许两个线程接触同一个对象吗?

这同样适用于:
IAsyncResult ar = BeginSetLabelToTheValueINeed(label1);
...
EndSetLabelToTheValueINeed(ar);

这同样适用于:
//Fetch image on connection that is an existing DB transaction
public static Bitmap GetImageThumbnail(DbConnection conn, int imageID)
{
}

被转换为异步委托(delegate)模式:
//Begin fetching an image on connection that is an existing DB transaction
IAsyncResult ar = BeginGetImageThumbnuts(conn, imageID, callback, stateOjbect);
...
//Finish fetching an image on connection that is an existing DB transaction
Bitmap thumb = EndGetImageNumbthail(ar);

人们没有回答这个问题,而是开始讨论 ADO.NET 中的设计模式。请回答问题。如果这些示例混淆并分散了您的松鼠大脑,请忽略这些示例。

最佳答案

.NET 对象未绑定(bind)到公寓。公寓只有在您的 .NET 代码与 COM 对象交互时才真正发挥作用,尽管在不知不觉中做到这一点并不难。例如,如果您与 Windows 剪贴板交互,您将激活 COM 子系统。套间是在线程级别设置的,一旦你的线程建立了它的套间(MTA、STA 等),它就不能改变,所以让套间正确是非常重要的。所有 WinForms 应用程序都将 [STAThread] 附加到它们的 Main() 方法,以确保主应用程序线程(即 GUI 消息泵线程)是 STA,并且可以与 Windows 剪贴板等便利设施进行交互。

.NET 运行时必须知道 COM 子系统才能提供 COM 互操作功能。虽然需要内在可怕的细节是非常罕见的。

据我了解,将 COM 对象划分为不同单元的目的之一是让应用程序可以使用使用不同线程模型开发的软件组件,而不必关心这些问题本身。

这里涉及很多复杂的问题,特别是单线程库通常不是为处理重入而构建的概念,当然也不支持让两个执行线程同时修改对象的概念。

例如,假设您想在新的多线程 C++ 应用程序中使用 COM 对象。此 COM 对象是在 Visual Basic 中开发的,不是线程安全的,但您希望从多个线程中使用该组件的多个实例。虽然确实可以添加一些锁定机制来防止不正确的访问,但对象存在于其自己的单线程单元 (STA) 中的事实意味着 COM 子系统将代表您序列化对对象的访问。您不必知道 COM 对象的线程模型即可使用它,或者至少它通常是这样工作的。

.NET 是为我们新的多线程世界编写的,因此不使用套间的概念。运行时肯定知道并且必须知道它们以支持与旧 COM 对象的互操作。

公寓非常复杂,如果您不知道自己在做什么,很多奇怪的事情都会出错。很高兴您在 .NET 中通常不需要担心它。

如果你想要一些非常核心的信息,你可以查看 Apartments and Pumping in the CLR .

关于.NET 框架 : Are objects apartment bound?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/306757/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com