Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程池-限制对某些方法的调用_C#_Multithreading_C# 4.0 - Fatal编程技术网

C# 线程池-限制对某些方法的调用

C# 线程池-限制对某些方法的调用,c#,multithreading,c#-4.0,C#,Multithreading,C# 4.0,有没有办法告诉线程池管理员只有x个线程调用一个特定的方法或一组方法 我有一个应用程序,在那里我到处使用线程池工作线程,它工作得很顺利;然而,我委托给工作线程的任务之一是web服务调用,它将拒绝5个以上的并发请求。我不想将线程池限制为5个线程,因为许多其他东西都使用线程,并且可以处理更多的线程 有没有一种方法可以“划分”线程池,即“在任何时间点,最多有x个线程在执行此特定任务,但其他线程可以执行其他任务”您可以使用多个线程池。对于Web服务的请求,线程池A最多有5个线程,线程池B最多有5个线程。创

有没有办法告诉线程池管理员只有x个线程调用一个特定的方法或一组方法

我有一个应用程序,在那里我到处使用线程池工作线程,它工作得很顺利;然而,我委托给工作线程的任务之一是web服务调用,它将拒绝5个以上的并发请求。我不想将线程池限制为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)线程是一个好主意,但我没有理由认为它不起作用。如此简单的测试当然值得!