using System; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; using System.Linq; public class ProxyManager { private List proxyPool = new List(); private object lockObj = new object(); private DateTime lastResetTime = DateTime.UtcNow; private TimeSpan resetInterval = TimeSpan.FromHours(1); // 设置重置间隔为1小时 public ProxyManager(IEnumerable proxyAddresses) { foreach (var address in proxyAddresses) { proxyPool.Add(new ProxyInfo(new WebProxy(address))); } } public WebProxy GetNextProxy() { lock (lockObj) { if (DateTime.UtcNow - lastResetTime >= resetInterval) ResetCounters(); var nextProxy = proxyPool.OrderBy(p => p.UsageCount).FirstOrDefault(p => p.IsAvailable); if (nextProxy != null) { nextProxy.UsageCount++; return nextProxy.Proxy; } return null; // 没有可用的代理时返回 null } } private void ResetCounters() { foreach (var proxyInfo in proxyPool) { proxyInfo.UsageCount = 0; } lastResetTime = DateTime.UtcNow; } public void ReportProxyResult(WebProxy proxy, bool isSuccess) { lock (lockObj) { var proxyInfo = proxyPool.Find(p => p.Proxy == proxy); if (proxyInfo != null) { if (isSuccess) { proxyInfo.Failures = 0; proxyInfo.IsAvailable = true; } else { proxyInfo.Failures++; proxyInfo.IsAvailable = false; proxyInfo.LastUnavailable = DateTime.UtcNow; if (proxyInfo.Failures >= 3) { proxyInfo.IsAvailable = false; SendAlert(proxyInfo); // 使用异步任务恢复代理可用状态 Task.Run(async () => { await Task.Delay(TimeSpan.FromMinutes(1)); lock (lockObj) { // 只有在这段时间内没有再次标记为不可用时才重置代理状态 if (!proxyInfo.IsAvailable) { proxyInfo.IsAvailable = true; } } }); } } } } } private void SendAlert(ProxyInfo proxyInfo) { Console.WriteLine($"Alert: Proxy {proxyInfo.Proxy.Address} is repeatedly failing."); } } public class ProxyInfo { public WebProxy Proxy { get; } public bool IsAvailable { get; set; } public int UsageCount { get; set; } public int Failures { get; set; } public DateTime LastUnavailable { get; set; } public ProxyInfo(WebProxy proxy) { Proxy = proxy; IsAvailable = true; UsageCount = 0; Failures = 0; LastUnavailable = DateTime.MinValue; } }