How to automatically initialize / uninitialize something globally for every thread?

别说谁变了你拦得住时间么 提交于 2019-12-22 09:53:42

问题


I have a unit with an initialization and finalization section. This unit contains a complex object which is instantiated in the initialization and destroyed in the finalization. However, this object also contains an ADO Connection. That makes it an issue when using this across threads, because ADO is COM, and needs to be initialized for every thread.

This is how I currently handle this global object instance:

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

This only works on the main thread. Any other thread wouldn't be able to access it, and will return an exception CoInitialize has not been called.

How do I get around this to make this unit thread-safe? I would need a way to hook every creation/destruction of any thread created, and each thread would need to refer to a different instance of this object. But how to go about doing so?


回答1:


Well, as you already say yourself, each thread needs to call CoInitialize separately. And in addition, each thread needs to have its own ADOConnection too.

I think you need to leave the idea of using the single global object/connection from that unit. Just repeat that object creation and destruction in each thread. When the thread types are different, then you could design a base thread class on top of them. If the object is too big (has overhead with regard to the thread) or does not 'fit' completely in the thread, then split the object design.

For now, your question sounds like just wanting to keep convenience, but if it is really necessary to centralize the ADO connection involvement, then maybe you could implement multi-cast events for the connection events of both main thread and the other threads. Logging in should not be a problem for successive connections: just store the login values and feed them to the threads.




回答2:


While another design might be a better solution, you can declare _MyObject as threadvar to have a separate instance for each thread. In addition you can move the CoInitialize/CoUnitialize into the constructor/destructor of TMyObject.

I cannot give advice on when to create and free these instances as I have no idea how your threads are created and freed.



来源:https://stackoverflow.com/questions/18807158/how-to-automatically-initialize-uninitialize-something-globally-for-every-thre

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!