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

时间:2012-04-19 19:41:30

标签: c# multithreading c#-4.0

有没有办法告诉线程池管理员只有 x 线程数量来调用特定方法或方法组?

我有一个应用程序,我在那里使用线程池工作线程,它可以游泳;然而,我委托给工作线程的任务之一是Web服务调用,它将拒绝超过5个并发请求。我不想将线程池限制为5个线程,因为许多其他东西使用线程并且可以处理更多。

有没有办法“划分”一个线程池,说“你将有最多的 x 线程在任何时候执行这个特定的事情,但其余的线程可以去做其他事情“?

4 个答案:

答案 0 :(得分:4)

使用信号量将对稀缺资源的访问限制为最大值。 5。

可以将信号量配置为仅允许N个线程的并发访问。您需要在N = 5时配置信号量,并在调用Web服务之前让所有线程等待它。

答案 1 :(得分:2)

创建另一个线程池和SetMaxThreads(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);
    }
};

}

它不像'真正的'System.Threading.Threadpool,但它是一个具有固定线程数的线程池

答案 2 :(得分:0)

您可以使用多个线程池。对于Web服务请求,最多有5个线程的线程池A,以及其他所有内容的线程池B最大值。

答案 3 :(得分:0)

首先,使用Task类而不是直接使用ThreadPool。启动循环遍历每个工作项的父任务并旋转子任务。父任务将使用信号量来限制并发子任务的数量。

这比你的子任务在信号量上等待要好得多,因为现在我们只有一个池化线程等待信号量,而不是很多。

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(); 
相关问题