C# 线程池-限制对某些方法的调用
有没有办法告诉线程池管理员只有x个线程调用一个特定的方法或一组方法 我有一个应用程序,在那里我到处使用线程池工作线程,它工作得很顺利;然而,我委托给工作线程的任务之一是web服务调用,它将拒绝5个以上的并发请求。我不想将线程池限制为5个线程,因为许多其他东西都使用线程,并且可以处理更多的线程C# 线程池-限制对某些方法的调用,c#,multithreading,c#-4.0,C#,Multithreading,C# 4.0,有没有办法告诉线程池管理员只有x个线程调用一个特定的方法或一组方法 我有一个应用程序,在那里我到处使用线程池工作线程,它工作得很顺利;然而,我委托给工作线程的任务之一是web服务调用,它将拒绝5个以上的并发请求。我不想将线程池限制为5个线程,因为许多其他东西都使用线程,并且可以处理更多的线程 有没有一种方法可以“划分”线程池,即“在任何时间点,最多有x个线程在执行此特定任务,但其他线程可以执行其他任务”您可以使用多个线程池。对于Web服务的请求,线程池A最多有5个线程,线程池B最多有5个线程。创
有没有一种方法可以“划分”线程池,即“在任何时间点,最多有x个线程在执行此特定任务,但其他线程可以执行其他任务”您可以使用多个线程池。对于Web服务的请求,线程池A最多有5个线程,线程池B最多有5个线程。创建另一个线程池并设置MaxThreads(5)-这是最简单的方法 好的,你不能用Threadpool类来做 这样我就不会被否决了:
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
BlockingCollection<Task> FinQueue;
public
PoolThread(BlockingCollection<Task> inQueue)
{
FinQueue=inQueue;
}
Task inMess;
public void run(){
while(true){
inMess=FinQueue.Take();
if(inMess==null) return;
try
{
inMess.run();
inMess.error = null;
}
catch (Exception e)
{
inMess.error = e;
}
inMess.FonComplete(inMess, null);
}
}
};
public class ThreadPool {
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);
}
};
}
公共抽象类任务{
公共事件处理程序已完成;
公共线程池myPool;
受保护的int参数;
公共例外错误;
公共任务(int-inParam,EventHandler-OnDone){param=inParam;FonComplete=OnDone;}
公开摘要无效运行();
};
公共类池线程{
私有的
阻塞收集队列;
公众的
PoolThread(阻塞队列中的集合)
{
FinQueue=inQueue;
}
任务管理;
公开募捐{
while(true){
inMess=FinQueue.Take();
if(inMess==null)返回;
尝试
{
inMess.run();
inMess.error=null;
}
捕获(例外e)
{
inMess.error=e;
}
inMess.FonComplete(inMess,null);
}
}
};
公共类线程池{
int-fthread计数;
阻塞收集队列;
void startThread(){
PoolThread thisPoolThread=新的PoolThread(队列);
Thread thisThread=新线程(newthreadstart(thisPoolThread.run));
thisThread.Priority=ThreadPriority.bellownormal;
thisThread.IsBackground=true;
thisThread.Start();
}
void SetThreadCount(int newCount){
while(FthreadCountnewCount){
添加(默认(任务));
线程计数--;
};
}
公共线程池(int initThreads){
队列=新建BlockingCollection();
对于(FthreadCount=0;FthreadCount值)
{
添加(默认(任务));
线程计数--;
}
}
}
公共作废提交(任务){
task.myPool=this;
添加(任务);
}
};
}
它不像“真正的”System.Threading.Threadpool,但它是一个线程数固定的线程池使用信号量将对稀缺资源的访问限制在最多5个
可以将信号量配置为仅允许N个线程的并发访问。您需要将信号量配置为N=5,并让所有线程在调用Web服务之前等待它。首先,使用
任务
类,而不是直接使用线程池。旋转父任务,循环遍历每个工作项并旋转子任务。父任务将使用信号量限制并发子任务的数量
这比让您的子任务等待信号量要好得多,因为现在我们只有一个池线程在等待信号量,而不是许多线程
var parent = Task.Factory.StartNew(
() =>
{
var semaphore = new SemaphoreSlim(5, 5);
foreach (var workitem in YourWorkItems)
{
var capture = workitem;
semaphore.Wait();
Task.Factory.StartNew(
() =>
{
try
{
CallWebService(capture);
}
finally
{
semaphore.Release();
}
}, TaskCreationOptions.AttachedToParent);
}
}, TaskCreationOptions.LongRunning);
// Optionally wait for the parent to complete here.
// Because our child tasks are attached this will wait until everything is done.
parent.Wait();
如何创建一个新的、独立的线程池?它似乎没有构造器。嗯……我在Java世界的时间似乎太多了。我想您需要创建自己的线程池来实现这一点,而这在这里可能不值得。这也是我的第一个想法:((再想一想,如果你不能创建另一个线程池实例-为什么?它是一个类,那么为什么我不能创建一个?对它施加限制是愚蠢的。我猜这个决定是为了防止子系统和库打开它们自己的池,并以倍数超额订阅CPU。这个决定是有问题的,但合理的。这是不合理的ble,IMHO。它正在吸取语言的灵活性。独立的子系统只是…正常!F..M$…我可能遗漏了一些东西,但似乎没有办法做到这一点。哇?我肯定我在什么地方读到过这一点?为什么Servy和我都立即想到了相同的答案?@MartinJames,直到你展示出你的可信度另一个线程池,这只是一个评论,不是一个答案。好吧,至少我正在尝试…:((这似乎是正确的方法;有点令人沮丧,这是必要的,但哦,好吧。你能解释一下吗?我不明白。不幸的是,在这种情况下,这不起作用。额外的线程池线程将在信号量上被阻塞。是的,它们将被阻塞,但线程池将只是被阻塞典当新的线程来替换它们。线程池可以检测到阻塞。哇,我以前从未听说过。我将尝试用我的大脑来处理它。我不太确定阻塞(提交的web任务的数量-5)线程是一个好主意,但我没有理由认为它不起作用。如此简单的测试当然值得!