Thi*_*dio 3 .net c# concurrency multithreading .net-4.5
我遇到了一个问题,我需要限制对另一个Web服务器的调用次数.它会有所不同,因为服务器是共享的,也许它可能有更多或更少的容量.
我在考虑使用SemaphoreSlim类,但是没有公共属性来更改最大计数.
我应该将我的SemaphoreSlim类包装在另一个将处理最大计数的类中吗?有没有更好的方法?
编辑:
这是我正在尝试的:
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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题:
1-_sem.Wait(1000)应该取消执行超过1000ms的线程,不是吗?
2 - 我是否有使用发布/等待的想法?
Jim*_*hel 10
您无法更改最大计数,但您可以创建SemaphoreSlim具有非常高的最大计数,并保留其中一些.请参阅此构造函数.
所以我们假设绝对最大并发调用数是100,但最初你希望它是25.你初始化你的信号量:
SemaphoreSlim sem = new SemaphoreSlim(25, 100);
Run Code Online (Sandbox Code Playgroud)
因此25是可以同时服务的请求数.你保留了其他75.
如果您想增加允许的数量,只需调用Release(num).如果你打电话Release(10),那么这个数字会达到35.
现在,如果要减少可用请求的数量,则必须WaitOne多次调用.例如,如果要从可用计数中删除10:
for (var i = 0; i < 10; ++i)
{
sem.WaitOne();
}
Run Code Online (Sandbox Code Playgroud)
这有可能阻塞,直到其他客户端释放信号量.也就是说,如果您允许35个并发请求,并且您希望将其减少到25,但是已经有35个客户端具有活动请求,那么WaitOne将阻塞直到客户端调用Release,并且循环将不会终止,直到10个客户端发布.
此时,您可以根据需要等待信号量(无需相应的释放调用)以降低容量。您可以多次释放信号量(无需相应的等待调用)以增加有效容量。
如果您已经做得足够多了,那么您可以创建自己的信号量类来组成SemaphoreSlim并封装此逻辑。如果您的代码已经释放了信号量而无需先等待它,那么这种组合也将是必不可少的;使用您自己的类,您可以确保此类发布是无操作的。(也就是说,你一开始就应该避免把自己置于这种境地,真的。)
| 归档时间: |
|
| 查看次数: |
2993 次 |
| 最近记录: |