在我的程序中,我可以加载目录:ICatalog
这里的目录包含许多refcounted结构(Itemlections of IItems,IElements,IRules等)
当我想换到另一个目录时, 我加载了一个新目录 但是以前的ICatalog实例的自动释放需要时间,冻结我的应用程序2秒或更长时间。
我的问题是:
我想将旧的(不再使用的)ICatalog实例的发布推迟到另一个线程。
我还没有测试过,但我打算用:
创建一个新线程ErazerThread.OldCatalog := Catalog; // old catalog refcount jumps to 2
Catalog := LoadNewCatalog(...); // old catalog refcount =1
ErazerThread.Execute; //just set OldCatalog to nil.
这样,我希望在线程中发布,而我的应用程序不会 蜜蜂已经冻结了。
安全(和良好做法)是否安全? 您是否已经使用类似方法获取现有代码的示例?
答案 0 :(得分:2)
看起来不错,但不要直接调用线程的Execute
方法;这将在当前线程中运行线程对象的代码,而不是线程对象创建的线程。请改为呼叫Start
或Resume
。
答案 1 :(得分:2)
我会让这样的线程阻塞在某些线程安全队列(*)上,并推送接口以iunknowns的形式释放到该队列中。
但是请注意,如果释放触及内存管理器使用的锁(如全局heapmanager锁),那么这是徒劳的,因为你的mainthread将阻塞第一个heapmanager访问。
使用每个线程池的堆管理器,在一个线程中分配许多项并在不同的线程中释放它可能会阻碍(小)块算法的合并和重用。
我仍然认为你描述的方式在正确实施时通常是合理的。但 这是从理论的角度来看,表明可能存在通过heapmanager从第二个线程到主线程的链接。
(*)最简单的方法是将它添加到tthreadlist并使用tevent来表示已添加元素。