我需要在我们的某个产品中添加第三方组件(这是一个可以全天候运行的Windows服务)。
3PC是一个.net库,它位于一些用于处理图像的硬核C ++可爱之上
3PC要求为其运行的每个线程调用 Initialize 和 Teardown 例程。
这在我们的旧软件中使用它很好,但是这个产品是用.Net线程池编写的,汇集的工作人员将使用3PC。我无法弄清楚如何安全地调用 Initialize 和 Teardown 例程。
我得到的最接近的是初始化ThreadStatic成员,调用3PC Initialize
方法,但是我无法在Teardown
所在的同一个线程上调用Initialize
呼吁。
如果我将Initialize
和Teardown
包装在一个对象中,并在对象Finalize方法中调用Teardown
,那么Teardown
将由GC自己调用完成线程,而不是线程对象是 static (更不用说不能保证Finalizer将会运行)。
显然我担心泄露的资源,因为线程池管理线程,我不知道线程是否会被销毁或创建,所以我不知道服务在一段时间内会泄漏多少。
任何想法?我错过了什么?还有别的尝试吗?
感谢
更新
问:拆解做什么?
我假设它“释放了一些记忆”,但老实说我不知道。我尝试使用Reflector通过程序集进行splunking,但很快就从IL中删除了本机代码。我要去(第3个)派对,必须这样做。
这肯定是一个子系统拆解的事情。
此外,几年前我们在另一个产品中发现了该组件的错误。没有为每个线程调用初始化程序,导致一些非常罕见的未定义行为。
答案 0 :(得分:4)
如果最糟糕的情况发生,并且没有更好的解决方案,那么你可以使用固定数量的线程创建自己的线程池(=内核数量?)。通过在每个线程中创建一个3PC实例并调用Initialize(),您应该可以,没问题。
类似的东西:
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading;
namespace WindowsPoolApp
{
public abstract class Task {
public EventHandler FonComplete;
public ThreadPool myPool;
protected int param;
public Exception error;
public Task(int inParam, EventHandler OnDone) { param = inParam; FonComplete = OnDone; }
public abstract void run();
};
public class PoolThread{
private
3PC my3PC;
BlockingCollection<Task> FinQueue;
public
PoolThread(BlockingCollection<Task> inQueue)
{
FinQueue=inQueue;
}
Task inMess;
public void run(){
my3PC = new 3PC();
my3PC.Initialize();
while(true){
inMess=FinQueue.Take();
if(inMess==null){
my3PC.Teardown();
return;
}
try
{
inMess.run();
inMess.error = null;
}
catch (Exception e)
{
inMess.error = e;
}
inMess.FonComplete(inMess, null);
}
}
};
public class ThreadPool {
volatile int FthreadCount;
BlockingCollection<Task> queue;
void startThread(){
PoolThread thisPoolThread=new PoolThread(queue);
Thread thisThread=new Thread(new ThreadStart(thisPoolThread.run));
thisThread.Priority = ThreadPriority.BelowNormal;
thisThread.IsBackground = true;
thisThread.Start();
}
void SetThreadCount(int newCount){
while(FthreadCount<newCount){startThread();};
while(FthreadCount>newCount){
queue.Add(default(Task));
FthreadCount--;
};
}
public ThreadPool(int initThreads){
queue=new BlockingCollection<Task>();
for(FthreadCount=0;FthreadCount<initThreads;FthreadCount++) startThread();
}
public int threadCount{
get{return FthreadCount;}
set
{
while (FthreadCount < value) {
startThread();
FthreadCount++;
};
while (FthreadCount > value)
{
queue.Add(default(Task));
FthreadCount--;
}
}
}
public void submit(Task task){
task.myPool=this;
queue.Add(task);
}
};
}
要启动它,请调用'new ThreadPool(numThreads);',关闭,将'threadCount'属性设置为0。