AngleSharp by AngleSharp

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

 BaseLoader

public abstract class BaseLoader : ILoader
Represents the base class for all loaders.
using AngleSharp.Dom; using AngleSharp.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 IEnumerable<IRequester> _requesters; private readonly IConfiguration _configuration; private readonly Predicate<IRequest> _filter; private readonly List<IDownload> _downloads; public BaseLoader(IEnumerable<IRequester> requesters, IConfiguration configuration, Predicate<IRequest> filter) { _requesters = requesters; _configuration = configuration; _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 _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) { foreach (IRequester requester in _requesters) { if (requester.SupportsProtocol(request.Address.Scheme)) { IEventAggregator events = _configuration.Events; RequestStartEvent evt = new RequestStartEvent(requester, request); events?.Publish(evt); IResponse result = await requester.RequestAsync(request, cancel).ConfigureAwait(false); evt.FireEnd(); return result; } } return null; } } }