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);
}
}
}
}