如何生成10个线程来处理字典?

时间:2015-03-30 13:09:48

标签: c# multithreading c#-4.0 dictionary asynchronous

我有一个用户名字典,我想检查这些用户是否可以用于登录网站,但是逐个迭代它会持续很长时间,因为它是一个巨大的列表,我希望它能够运行最多10个线程,一次测试10个。

Dictionary<string, string> test = new Dictionary<string,string>;
test.Add("user1", "pass1");
test.Add("user2", "pass2");
...
test.Add("user999", "pass999");

如何生成10个线程并对其进行处理,然后将所有结果合并到一个只包含通过登录测试的用户的新词典中?站点示例(不是真实站点,仅用于演示此函数对于成功登录返回true而对于错误登录则返回false)。

private bool IsLoginSuccess(string u, string p)
{
  WebClient wc = new WebClient();
  string str = wc.DownloadString("http://www.samplesite.com?user=" + u + "&pass=" p);
  if (str == "1") return true;
  return false;
}

1 个答案:

答案 0 :(得分:2)

首先,如果您希望使用大量连接到单个站点,您可能希望调整流程配置以允许这样做 - 否则您会发现您在WebClient上遇到了瓶颈。请参阅<connectionManagement> app.config element

最简单的方法可能是使用ConcurrentDictionary来收集结果,并使用Parallel.ForEach来处理多个线程中的原始字典。 (从多个线程中读取字典是安全的,只要没有任何内容写入它。)

var results = new ConcurrentDictionary<string, string>();
Parallel.ForEach(test,
    new ParallelOptions { MaxDegreeOfParallelism = 10 },
    pair =>
    {
        if (IsLoginSuccess(pair.Key, pair.Value))]
        {
            results[pair.Key] = pair.Value;
        }
    });

或者,您可以使用异步请求执行所有操作 - 使用C#5比使用C#4更容易。请注意。