AngleSharp by AngleSharp

<PackageReference Include="AngleSharp" Version="0.9.7" />

 BaseLoader

public abstract class BaseLoader : ILoader
Represents the base class for all loaders.
using AngleSharp.Dom; using AngleSharp.Dom.Events; using AngleSharp.Extensions; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.Network.Default { public abstract class BaseLoader : ILoader { private readonly IBrowsingContext _context; private readonly Predicate<IRequest> _filter; private readonly List<IDownload> _downloads; public BaseLoader(IBrowsingContext context, Predicate<IRequest> filter) { _context = context; _filter = (filter ?? ((Predicate<IRequest>)((IRequest _) => true))); _downloads = new List<IDownload>(); } protected virtual void Add(IDownload download) { lock (this) { _downloads.Add(download); } } protected virtual void Remove(IDownload download) { lock (this) { _downloads.Remove(download); } } protected virtual string GetCookie(Url url) { return _context.Configuration.GetCookie(url.Origin); } protected virtual IDownload DownloadAsync(Request request, INode originator) { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); if (_filter(request)) { Task<IResponse> task = LoadAsync(request, cancellationTokenSource.Token); Download download = new Download(task, cancellationTokenSource, request.Address, originator); Add(download); task.ContinueWith(delegate { Remove(download); }); return download; } return new Download(TaskEx.FromResult<IResponse>(null), cancellationTokenSource, request.Address, originator); } public IEnumerable<IDownload> GetDownloads() { lock (this) { return _downloads.ToArray(); } } protected async Task<IResponse> LoadAsync(Request request, CancellationToken cancel) { IEnumerable<IRequester> services = _context.Configuration.GetServices<IRequester>(); foreach (IRequester item in services) { if (item.SupportsProtocol(request.Address.Scheme)) { _context.Fire(new RequestEvent(request, null)); IResponse response = await item.RequestAsync(request, cancel).ConfigureAwait(false); _context.Fire(new RequestEvent(request, response)); return response; } } return null; } } }