Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.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# 如何将一个方法限制为n个并发调用_C#_Multithreading_.net 4.0_Concurrency - Fatal编程技术网

C# 如何将一个方法限制为n个并发调用

C# 如何将一个方法限制为n个并发调用,c#,multithreading,.net-4.0,concurrency,C#,Multithreading,.net 4.0,Concurrency,我有一个集成服务,它运行一个计算量大、数据绑定的过程。我想确保这些进程在同一时间运行的次数不超过n=5(但n将是可配置的,在运行时是可更改的)。其想法是将服务器上的负载限制在安全级别。该方法处理的数据量受到批处理的限制,因此我不需要担心一个进程比另一个进程代表更大的负载 处理方法由另一个进程调用,其中运行工资单的请求保存在队列中,我可以在该点插入一些逻辑来确定是现在处理该请求,还是将其留在队列中 因此,我希望在与处理方法相同的服务上有一个单独的方法,它可以告诉我服务器是否可以接受对处理方法的另一

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

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

因此,我希望在与处理方法相同的服务上有一个单独的方法,它可以告诉我服务器是否可以接受对处理方法的另一个调用。它会问,“有多少人在发工资?少于n吗?”实现这一点的好方法是什么

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


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

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

另见

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


另请参见

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

另见

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

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

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

void ThreadTest()
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();
    }
}
{ ConcurrentQueue q=新的ConcurrentQueue(); int MaxCount=5; 随机r=新随机(); 对于(int i=0;i { int read=0; if(q.TryDequeue(读出)) { WriteLine(String.Format(“[{1:HH:mm:ss}.{1:fff}]起始:{0}…@Thread{2}”,读取,DateTime.Now,Thread.CurrentThread.ManagedThreadId)); 睡眠(r.Next(1001000)); WriteLine(String.Format(“[{1:HH:mm:ss}.{1:fff}]{0}结束!@Thread{2}”,读取,DateTime.Now,Thread.CurrentThread.ManagedThreadId)); proc(); } }; 对于(int i=0;i
void ThreadTest()
{
ConcurrentQueue q=新的ConcurrentQueue();
int MaxCount=5;
随机r=新随机();
对于(int i=0;i
{
int read=0;
if(q.TryDequeue(读出))
{
WriteLine(String.Format(“[{1:HH:mm:ss}.{1:fff}]起始:{0}…@Thread{2}”,读取,DateTime.Now,Thread.CurrentThread.ManagedThreadId));
睡眠(r.Next(1001000));
WriteLine(String.Format(“[{1:HH:mm:ss}.{1:fff}]{0}结束!@Thread{2}”,读取,DateTime.Now,Thread.CurrentThread.ManagedThreadId));
proc();
}
};

对于(inti=0;i您可以使用
信号量来执行此操作

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();
        }
    }
}

您可以使用
信号灯来执行此操作

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();
        }
    }
}

我不熟悉线程编程(因此有一个注释),但在我看来,这对于线程池来说是一个完美的工作。您可能只需要使用一个信号量我不熟悉线程编程(因此有一个注释),但在我看来,这对线程池来说是一个完美的工作。你可以只使用一个信号量。这并不限制被调用方的任何操作,它只通过创建有限数量的线程来从调用方执行。这不是问题所要问的。他希望被调用方限制访问,假设线程数量超出预期您正在尝试访问该方法。我想您不明白。您不执行调用,而是使用要处理的数据填充集合。您可以在代码中的任意位置配置线程数量。这并不限制被调用方的任何操作,它只通过创建有限数量的线程从调用方执行。这是这不是问题所要求的。他希望被调用方限制访问,前提是尝试访问该方法的线程数量超出预期。我想你不明白。你不执行调用,而是用你想要处理的数据填充一个集合。你可以在代码中的任意位置配置线程数量。这是限制从caller端,而不是callee端。这并不总是可能的,也不是OP所要求的。如果这是ASP应用程序内部,并且他不希望有太多的请求同时ping这个外部资源,该怎么办?您不希望将线程池限制为少量线程,因为这会降低ASP应用程序上所有其他处理的速度在这个网站上,你只想限制对这一资源的访问。我很确定我确实想阻止来自呼叫者端的访问。如果我阻止呼叫者端的请求,当它们还没有准备好的时候,它们仍然会在我的服务中飞来飞去。我认为这最适合我想要的,尽管我后来意识到我可以跟踪需要多少工作出现在调用方而不必询问工作人员这限制了从调用方而不是被调用方的访问。这并不总是可能的,也不是OP要求的。如果这是在ASP应用程序内部,他不希望有太多的请求ping,该怎么办