【问题标题】:C# return string of proxy from list non-repeat / thread-safeC#从列表非重复/线程安全返回代理字符串
【发布时间】:2019-12-20 18:16:53
【问题描述】:

基本上,我发现我的网络请求只是在我正在做的网络抓取项目中反复使用相同的代理。

public static List<string> proxyLogs = new List<string>();
private static Random random = new Random();

public static string randomizeProxy(List<string> proxies = null)
{
    if (proxies == null)
       proxies = proxyLogs;

    return proxies[random.Next(proxies.Count)];
}

Parallel.ForEach(concurrentLogs, new ParallelOptions { MaxDegreeOfParallelism = 4}, log =>
{
//my http requests
string proxyLog = randomizeProxy(proxyLogs);
Console.WriteLine(proxyLog);
});

所以并行选项线程设置为 4,它所做的 4 个请求是一遍又一遍地使用相同的代理,并且每个线程没有不同。

这似乎是最好的方法?

【问题讨论】:

  • 嗨@Amy,我担心的是,在线程处理时,proxyLog 的值会重复。
  • 我理解您的担忧。仔细阅读我链接的内容并保护对 Random 类的访问。
  • @AnnaP。欢迎来到堆栈溢出。请通过tour 了解 Stack Overflow 的工作原理,并阅读How to Ask 以了解如何提高问题的质量。然后edit 你的问题包括你作为minimal reproducible example 的完整源代码,其他人可以编译和测试。您还没有展示getRandomProxy() 的作用、proxyLogs 的填充方式或concurrentLogs 的大小。
  • 您不想要随机项目,因为随机选择可以重复。您真正想要的是获取一个列表,将顺序随机化,然后以新的随机顺序浏览列表。

标签: c# multithreading thread-safety parallel.foreach


【解决方案1】:

任何不需要并行的东西,放在 ForEach 之外。没有理由需要在那里进行随机数选择(尤其是因为它不是线程安全的)。

var data = concurrentLogs.Select
(
    log => new { Log = log, Proxy = randomizeProxy(proxyLogs) } 
).ToList();
Parallel.ForEach( data, new ParallelOptions (MaxDegreeOfParallelism = 4}, item =>
{
    var log = item.Log;
    var proxyLog = item.Proxy;
    Console.WriteLine(proxyLog);
});

【讨论】:

    猜你喜欢
    • 2018-03-08
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多