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

查看:38
本文介绍了具有动态 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 类,但没有更改最大计数的公共属性.

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) 应该取消执行超过 1000 毫秒的线程的执行,不是吗?

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

2-我有没有想到使用 Release/Wait?

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.

如果您想增加允许的数量,只需调用 发布(编号).如果您调用 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天全站免登陆