gpt4 book ai didi

.net - 无论如何要知道池线程(或 ThreadStatic 成员)何时被销毁?

转载 作者:行者123 更新时间:2023-12-01 01:18:57 28 4
gpt4 key购买 nike

我需要将第三方组件添加到我们的一个产品中(这是一种可以 24/7 全天候运行的 Windows 服务)。
3PC 是一个 .net 库,它基于一些核心的 C++ 可爱操作图像。
3PC 要求为它运行的每个线程调用 Initialize 和 Teardown 例程。
这在我们在旧软件中使用它的地方很好,但是这个产品是用 .Net 线程池编写的,池化 worker 将使用 3PC。我不知道如何安全地调用 Initialize 和 Teardown 例程。

我最接近的是在初始化 ThreadStatic 成员时调用 3PC Initialize方法,但是我无法调用 Teardown在同一线程 Initialize被召唤。

如果我包装 InitializeTeardown在一个对象中,使用 Teardown在对象的 Finalize 方法中调用,然后是 Teardown将被 GC 自己的 Finalize 线程调用,而不是对象静态的线程(更不用说不能保证 Finalizer 将永远运行的事实)。

显然我担心泄漏的资源,因为线程池在幕后管理线程,我不知道线程是否或何时会被销毁或创建 ,所以我不知道在一段时间内服务可能会泄漏多少。

有人有什么想法吗?我错过了什么吗?还有什么可以尝试的吗?
谢谢

更新

问:Teardown 有什么作用?

我假设它“释放一些内存”,但老实说我不知道​​。我尝试使用 Reflector 遍历程序集,但它很快从 IL 下降到 native 机器代码。我要在(第三)方路线上,这必须完成。

这绝对是一个子系统拆卸的东西。

此外,几年前,我们在另一个产品中发现了有关此组件的错误。并不是每个线程都调用了 Initializer,这导致了一些非常罕见的未定义行为。

最佳答案

如果最坏的情况出现,并且没有更好的解决方案,您可以使用固定数量的线程(=核心数?)创建自己的线程池。通过在每个线程中创建一个 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。

关于.net - 无论如何要知道池线程(或 ThreadStatic 成员)何时被销毁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10399680/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com