没什么好说的,看代码。。。。 namespace XUtils.Net { /******************************************************************** * Copyright: 2009-2011 * Company: CFO * CRL Version : 4.0.30319.1 * Created by 徐毅 at 2011/1/15 23:25:12 * mailto:。。。。 * 集团技术研发中心 ********************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; using System.Data; using System.Threading; using System.Diagnostics; using XUtils; using XUtils.Serialization; /// <summary> /// 流量控制 /// </summary> public class FlowControl : TimerBase { private static object syncLock = new object(); private static FlowControl flow = null; private decimal _setSize = 128 * 8; private decimal _netBytes = 0; private decimal _Kbyte = 1024; private Action<decimal> _actionMonitoring = null; public FlowControl() : base(1000) { this.timer.AutoReset = true; this.timer.Start(); } public static FlowControl Singleton { get { if (flow == null) { lock (syncLock) { if (flow == null) flow = new FlowControl(); } } return flow; } } public override void timer_Elapsed(object sender, ElapsedEventArgs e) { if (_actionMonitoring != null) _actionMonitoring.Invoke(this._netBytes / 8); } /// <summary> /// 监控每秒流量 /// </summary> /// <param name="action"></param> public void Monitoring(Action<decimal> action) { _actionMonitoring = action; } /// <summary> /// 流量控制 /// </summary> /// <param name="dataTable"></param> /// <param name="Callback"></param> public void Limit(DataTable dataTable, Action<DataRow[]> Callback) { Monitor.Enter(syncLock); if (dataTable == null || Callback == null) return; decimal _mSize = _setSize; //复制表结构 DataTable newDataTable = dataTable.Clone(); List<DataRow> rows = new List<DataRow>(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Array.ForEach<DataRow>(dataTable.Select(), (dr) => { //清除计算表 newDataTable.Clear(); //复制新的DataRow行进行计算 newDataTable.ImportRow(dr); rows.Add(dr); try { //获取单条记录byte byte[] newDataTableByte = FormatterHelper.Serialize(newDataTable); decimal drKB = newDataTableByte.Length / _Kbyte; //单位限制的剩余流量 _mSize -= drKB; //总流量 _netBytes += drKB; } catch { } //如果流量超过了限制数 if (_mSize < 0) { //时间再一秒内 则休眠 if (stopwatch.Elapsed.Milliseconds < 1000) Thread.Sleep(1000 - stopwatch.Elapsed.Milliseconds); Callback.Invoke(rows.ToArray()); rows.Clear(); //重启计时器 stopwatch.Reset(); stopwatch.Start(); //初始化限制 _mSize = _setSize; _netBytes = 0; } }); Callback.Invoke(rows.ToArray()); _netBytes = 0; Monitor.Exit(syncLock); } /// <summary> /// 流量控制 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entities"></param> /// <param name="Callback"></param> public void Limit<TEntity>(List<TEntity> entities, Action<TEntity[]> Callback) where TEntity : class,new() { Monitor.Enter(syncLock); if (entities == null || Callback == null || entities.Count == 0) return; decimal _mSize = _setSize; //复制表结构 List<TEntity> newEntities = new List<TEntity>(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Array.ForEach<TEntity>(entities.ToArray(), (entity) => { newEntities.Add(entity); try { //获取单条记录byte byte[] newEntityByte = FormatterHelper.Serialize(entity); decimal kb = newEntityByte.Length / _Kbyte; //单位限制的剩余流量 _mSize -= kb; //总流量 _netBytes += kb; } catch { } //如果流量超过了限制数 if (_mSize < 0) { //时间再一秒内 则休眠 if (stopwatch.Elapsed.Milliseconds < 1000) Thread.Sleep(1000 - stopwatch.Elapsed.Milliseconds); Callback.Invoke(newEntities.ToArray()); newEntities.Clear(); //重启计时器 stopwatch.Reset(); stopwatch.Start(); //初始化限制 _mSize = _setSize; _netBytes = 0; } }); Callback.Invoke(newEntities.ToArray()); _netBytes = 0; Monitor.Exit(syncLock); } /// <summary> /// 每秒写入大小 /// <remarks>单位KB</remarks> /// </summary> public decimal Size { get { return _setSize / 8; } set { lock (syncLock) _setSize = value * 8; } } } }