具有动态maxCount的SemaphoreSlim [英] SemaphoreSlim with dynamic maxCount

查看:215
本文介绍了具有动态maxCount的SemaphoreSlim的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个问题,我需要限制对另一个Web服务器的调用次数。它会有所不同,因为服务器是共享的,也许它可能有更多或更少的容量。

I'm facing a problem where I need to limit the number of calls to another web server. It will vary because the server is shared and maybe it could have more or less capacity.

我正在考虑使用SemaphoreSlim类,但没有公共属性更改max计数。

I was thinking about using SemaphoreSlim class, but there's no public property to change the max count.

我应该将我的SemaphoreSlim类包装在另一个能处理最大计数的类中吗?是否有更好的方法?

Should I wrap my SemaphoreSlim class in another class that will handle the max count? Is there any better approach?

编辑:

这是我想要的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Semaphore
{
class Program
{
    static SemaphoreSlim _sem = new SemaphoreSlim(10,10000);

    static void Main(string[] args)
    {
        int max = 15;

        for (int i = 1; i <= 50; i++)
        {
            new Thread(Enter).Start(new int[] { i, max});
        }

        Console.ReadLine();

        max = 11;

        for (int i = 1; i <= 50; i++)
        {
            new Thread(Enter).Start(new int[] { i, max });
        }
    }

    static void Enter(object param)
    {
        int[] arr = (int[])param;
        int id = arr[0];
        int max = arr[1];

        try
        {
            Console.WriteLine(_sem.CurrentCount);

            if (_sem.CurrentCount <= max)
                _sem.Release(1);
            else
            {
                _sem.Wait(1000);

                Console.WriteLine(id + " wants to enter");

                Thread.Sleep((1000 * id) / 2); // can be here at

                Console.WriteLine(id + " is in!"); // Only three threads

            }
        }
        catch(Exception ex)
        {
            Console.WriteLine("opps ", id);
            Console.WriteLine(ex.Message);
        }
        finally            
        {
            _sem.Release();
        }
    }
}
}

1-_sem.Wait(1000)应该取消执行超过1000ms的线程,不是吗?

1-_sem.Wait(1000) should cancel the execution of threads that will execute for more than 1000ms, wasn't it?

2 - 我有使用释放/等待的想法吗?

2-Did I got the idea of using Release / Wait?

推荐答案

更改最大计数,但您可以创建一个具有非常高的最大计数的 SemaphoreSlim ,并保留其中一些。请参见此构造函数

You can't change the max count, but you can create a SemaphoreSlim that has a very high maximum count, and reserve some of them. See this constructor.

因此,我们假设并发呼叫的绝对最大值数是100,但最初你想要它为25.你初始化你的信号量:

So let's say that the absolute maximum number of concurrent calls is 100, but initially you want it to be 25. You initialize your semaphore:

SemaphoreSlim sem = new SemaphoreSlim(25, 100);

所以25是可以并发服务的请求数。您已保留其他75个。

So 25 is the number of requests that can be serviced concurrently. You have reserved the other 75.

如果您想增加允许的数量,只需调用版本(num)。如果你调用 Release(10),那么数字将变成35。

If you then want to increase the number allowed, just call Release(num). If you called Release(10), then the number would go to 35.

减少可用请求的数量,您必须多次调用 WaitOne 。例如,如果要从可用计数中删除10:

Now, if you want to reduce the number of available requests, you have to call WaitOne multiple times. For example, if you want to remove 10 from the available count:

for (var i = 0; i < 10; ++i)
{
    sem.WaitOne();
}

这有可能阻塞,直到其他客户端释放信号量。也就是说,如果您允许35个并发请求,并且希望将其减少到25个,但已经有35个客户端具有活动请求,则 WaitOne 将阻塞,直到客户端调用 Release ,并且在10个客户端释放之前,循环将不会终止。

This has the potential of blocking until other clients release the semaphore. That is, if you allow 35 concurrent requests and you want to reduce it to 25, but there are already 35 clients with active requests, that WaitOne will block until a client calls Release, and the loop won't terminate until 10 clients release.

这篇关于具有动态maxCount的SemaphoreSlim的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆