延迟添加队列
using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace AnfleCrawler.Common { /// <summary> /// 延迟添加队列 /// </summary> internal class LagPattern : Disposable { private static readonly List<LagPattern> Set = new List<LagPattern>(); private const double PerCount = 50d; private WeakReference _weakRef; private int _depth; private object _state; private JobTimer _job; private PageCrawler Weak { get { if (!_weakRef.IsAlive) { throw new InvalidOperationException("Wrap Dead"); } return (PageCrawler)_weakRef.Target; } } public LagPattern(PageCrawler wrap, StringPatternGenerator urlGen, int depth, object state) { Contract.Requires(wrap != null && urlGen != null); _weakRef = new WeakReference(wrap); _depth = depth; _state = state; var tor = urlGen.GetEnumerator(); int totalCount = urlGen.Count(); if (totalCount < PerCount) { Proc(tor); return; } double span = Math.Ceiling(360d / (totalCount / PerCount)); //double span = 16d; App.LogInfo("LagPattern Span:{0}", span); _job = new JobTimer(Proc, TimeSpan.FromSeconds(span)); _job.Start(tor); //App.DisposeService.Register(this.GetType(), this); lock (Set) { Set.Add(this); } } protected override void DisposeInternal(bool disposing) { if (disposing) { if (_job != null) { _job.Dispose(); } //App.DisposeService.Release(this.GetType(), this); lock (Set) { Set.Remove(this); } } } private void Proc(object state) { var wrap = this.Weak; var urlGen = (IEnumerator<string>)state; for (int i = 0; i < PerCount; i++) { if (!urlGen.MoveNext()) { this.Dispose(); return; } wrap.PushUrl(new Uri(urlGen.Current), _depth, _state); } } } }