我有一个用户名字典,我想检查这些用户是否可以用于登录网站,但是逐个迭代它会持续很长时间,因为它是一个巨大的列表,我希望它能够运行最多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;
}
答案 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更容易。请注意。