1

我有一个集成服务,它运行计算繁重的数据绑定过程。我想确保同时运行的这些进程不会超过 n = 5(但 n 将是可配置的,可在运行时更改)。这个想法是将服务器上的负载限制在安全水平。该方法处理的数据量受到批处理的限制,因此我不必担心一个进程代表比另一个更大的负载。

处理方法由另一个进程调用,其中运行工资单的请求保存在队列中,我可以在此时插入一些逻辑来确定是现在处理此请求,还是将其留在队列中。

所以我想要一个与处理方法在同一服务上的单独方法,它可以告诉我服务器是否可以接受对处理方法的另一个调用。它会问,“有多少工资单正在运行?这是否小于 n?” 实现这一目标的巧妙方法是什么?

- - - - - -编辑 - - - - - -

我想我需要说清楚,决定是否将请求从队列中取出的过程与通过 WCF 边界处理工资单数据的服务分开。停止工资单处理过程中的线程不会阻止更多请求进入

4

4 回答 4

4

您可以使用 aSemaphore来执行此操作。

public class Foo
{
    private Semaphore semaphore;
    public Foo(int numConcurrentCalls)
    {
        semaphore = new Semaphore(numConcurrentCalls, numConcurrentCalls);
    }

    public bool isReady()
    {
        return semaphore.WaitOne(0);
    }

    public void Bar()
    {
        try
        {
            semaphore.WaitOne();//it will only get past this line if there are less than 
            //"numConcurrentCalls" threads in this method currently.
            //do stuff
        }
        finally
        {
            semaphore.Release();
        }
    }
}
于 2012-12-14T14:53:36.197 回答
1

查看对象池模式。这就是你所描述的。虽然模式没有严格要求,但您可以公开当前池中的对象数量、最大(配置的)数量、高水位线等。

于 2012-12-14T14:25:07.613 回答
0
void ThreadTest()
{
    ConcurrentQueue<int> q = new ConcurrentQueue<int>();
    int MaxCount = 5;
    Random r = new Random();

    for (int i = 0; i <= 10000; i++)
    {
        q.Enqueue(r.Next(100000, 200000));
    }

    ThreadStart proc = null;
    proc = () =>
    {
        int read = 0;
        if (q.TryDequeue(out read))
        {
            Console.WriteLine(String.Format("[{1:HH:mm:ss}.{1:fff}] starting: {0}... @Thread {2}", read, DateTime.Now, Thread.CurrentThread.ManagedThreadId));
            Thread.Sleep(r.Next(100, 1000));
            Console.WriteLine(String.Format("[{1:HH:mm:ss}.{1:fff}] {0} ended! @Thread {2}", read, DateTime.Now, Thread.CurrentThread.ManagedThreadId));
            proc();
        }
    };

    for (int i = 0; i <= MaxCount; i++)
    {
        new Thread(proc).Start();
    }
}
于 2012-12-14T14:48:17.590 回答
0

我认为您可能需要一个BlockingCollection,其中集合中的每个项目代表一个并发调用。

另请参阅IProducerConsumerCollection

如果您只是使用线程,我建议您查看限制线程并发性的方法(例如TaskScheduler.MaximumConcurrencyLevel属性和此示例。)。

另请参阅ParallelEnumerable.WithDegreeOfParallelism

于 2012-12-14T14:24:00.203 回答