3

我有一个带有initializationfinalization部分的单元。该单元包含一个复杂对象,该对象在 中实例化initialization并在 中销毁finalization。但是,此对象还包含一个 ADO 连接。这使得跨线程使用它时成为一个问题,因为 ADO 是 COM,并且需要为每个线程初始化。

这就是我目前处理这个全局对象实例的方式:

uses
  ActiveX;
...
initialization
  CoInitialize(nil);
  _MyObject:= TMyObject.Create;
finalization
  _MyObject.Free;
  CoUninitialize;
end.

这仅适用于主线程。任何其他线程都无法访问它,并且会返回异常CoInitialize has not been called

我如何解决这个问题以使这个单元线程安全?我需要一种方法来挂钩创建的任何线程的每次创建/销毁,并且每个线程都需要引用该对象的不同实例。但是如何去做呢?

4

2 回答 2

8

好吧,正如您自己已经说过的,每个线程都需要CoInitialize单独调用。此外,每个线程也需要有自己的线程ADOConnection

我认为您需要放弃使用该单元中的单个全局对象/连接的想法。只需在每个线程中重复该对象的创建和销毁。当线程类型不同时,您可以在它们之上设计一个基本线程类。如果对象太大(线程有开销)或不完全“适合”线程,则拆分对象设计。

目前,您的问题听起来只是想保持方便,但如果确实需要集中 ADO 连接参与,那么也许您可以为主线程和其他线程的连接事件实现多播事件。对于连续连接,登录应该不是问题:只需存储登录值并将它们提供给线程。

于 2013-09-14T23:08:07.133 回答
4

虽然另一种设计可能是更好的解决方案,但您可以将 _MyObject 声明threadvar为每个线程都有一个单独的实例。此外,您可以将 CoInitialize/CoUnitialize 移动到 TMyObject 的构造函数/析构函数中。

我无法就何时创建​​和释放这些实例提供建议,因为我不知道您的线程是如何创建和释放的。

于 2013-09-15T07:46:59.860 回答