我的单元有initialization
和finalization
部分。此单元包含一个复杂对象,该对象在initialization
中实例化并在finalization
中销毁。但是,此对象还包含ADO连接。这使得在跨线程使用它时会出现问题,因为ADO是COM,需要为每个线程初始化。
这就是我目前处理这个全局对象实例的方式:
uses
ActiveX;
...
initialization
CoInitialize(nil);
_MyObject:= TMyObject.Create;
finalization
_MyObject.Free;
CoUninitialize;
end.
这仅适用于主线程。任何其他线程都无法访问它,并将返回异常CoInitialize has not been called
。
如何解决这个问题,使这个单元具有线程安全性?我需要一种方法来挂钩创建的任何线程的每个创建/销毁,并且每个线程都需要引用该对象的不同实例。但是如何去做呢?
答案 0 :(得分:8)
好吧,正如您已经说过的那样,每个线程都需要单独调用CoInitialize
。此外,每个线程也需要有自己的ADOConnection
。
我认为您需要保留使用该单元中的单个全局对象/连接的想法。只需在每个线程中重复创建和销毁对象。当线程类型不同时,您可以在它们之上设计基本线程类。如果对象太大(有关于线程的开销)或者不完全“适合”线程,则拆分对象设计。
现在,您的问题听起来只是想保持方便,但如果真的有必要集中ADO连接参与,那么也许您可以为主线程和其他线程的连接事件实现多播事件。登录对于连续连接应该不是问题:只需存储登录值并将它们提供给线程。
答案 1 :(得分:4)
虽然另一种设计可能是更好的解决方案,但您可以将_MyObject声明为threadvar
,以便为每个线程提供单独的实例。此外,您可以将CoInitialize / CoUnitialize移动到TMyObject的构造函数/析构函数中。
我无法就何时创建和释放这些实例给出建议,因为我不知道如何创建和释放您的线程。