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 static WebProxy Parse(string proxy) { if (string.IsNullOrEmpty(proxy)) { throw new ArgumentNullException(nameof(proxy)); } try { string username = ""; string password = ""; string proxy_url = ""; string scheme = "http://"; // 默认使用http // 检查是否指定了协议 if (proxy.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || proxy.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { // 提取协议 var schemeEnd = proxy.IndexOf("://"); scheme = proxy[..(schemeEnd + 3)]; proxy = proxy[(schemeEnd + 3)..]; } // 检查是否包含认证信息 if (proxy.Contains("@")) { var parts = proxy.Split('@'); if (parts.Length == 2) { var credentials = parts[0].Split(':'); if (credentials.Length == 2) { username = credentials[0]; password = credentials[1]; } proxy_url = parts[1]; } } else { proxy_url = proxy; } // 构造完整的代理URL proxy_url = scheme + proxy_url; return new WebProxy { Address = new Uri(proxy_url), Credentials = !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password) ? new NetworkCredential(username, password) : null }; } catch (Exception ex) { throw new FormatException($"Failed to parse proxy string: {ex.Message}"); } } 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; } }