using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TokenBucketLib
{
///
/// 队列令牌桶
/// 资源请求首先到达令牌桶,如果获得令牌马上返回,如果失败将进入等待队列,等待获得令牌后返回,或者令牌桶满后获取失败并丢弃。
///
public class QueueTokenBucket : TokenBucket
{
///
/// 最大缓冲对列数。-1为不限长度。
///
public int QueueMaxLenth { get; set; }
private Queue queue;
private readonly static object objlock = new object();
///
/// 构造一个带缓冲队列的令牌桶
///
public QueueTokenBucket()
: this(-1)
{
}
///
/// 通过提供最大缓冲队列数构造缓冲队列令牌桶
///
/// 缓冲区大小。-1为不限制大小。
public QueueTokenBucket(int queueMaxLenth)
{
QueueMaxLenth = queueMaxLenth;
queue = new Queue();
base.Put += new Action(QueueTokenBuket_Put);
}
private void QueueTokenBuket_Put(TokenBucket obj)
{
if (queue.Count > 0)
{
lock (objlock)
{
var c = queue.Count;
for (int i = 0; i < c; i++)
{
var r = base.GetToken();
if (r.State == TokenBucketPassEnum.passed)
{
TokenBucketPass result = queue.Dequeue();
result.State = TokenBucketPassEnum.passed;
if (GetTokenEnd != null) GetTokenEnd(this, new TokenBucketEventArgs(result));
}
else
{
break;
}
}
}
}
}
///
///
///
public event Action GetTokenEnd;
///
/// 开始异步获取令牌
///
/// 异步传入的对象,这个对象会随TokenBucketPass.Requester传出。
public void GetTokenAsyn(object requester)
{
var result = new TokenBucketPass();
result.Requester = requester;
var r = base.GetToken();
if (r.State == TokenBucketPassEnum.passed)
{
result.State = r.State;
if (GetTokenEnd != null) GetTokenEnd(this, new TokenBucketEventArgs(result));
}
else
{
if (QueueMaxLenth != -1 && QueueMaxLenth < queue.Count)
{
result.State = TokenBucketPassEnum.losted;
GetTokenEnd(this, new TokenBucketEventArgs(result));
}
else
{
queue.Enqueue(result);
}
}
}
#region IDisposable 成员
protected override void Dispose(bool disposing)
{
if (disposing)
{
queue.Clear();
}
base.Dispose(disposing);
}
#endregion
}
}