C# 为什么在使用Parallel.For时会导致ArgumentOutOfRangeException?
我尝试过写一些东西来散列数字,并对照列表检查它们,看看是否存在匹配的散列 我使用for循环工作得很好,然后我决定尝试使用Parallel来加快速度C# 为什么在使用Parallel.For时会导致ArgumentOutOfRangeException?,c#,multithreading,blockingcollection,parallel.for,C#,Multithreading,Blockingcollection,Parallel.for,我尝试过写一些东西来散列数字,并对照列表检查它们,看看是否存在匹配的散列 我使用for循环工作得很好,然后我决定尝试使用Parallel来加快速度 public class HashCompare { private string encryptedCardNumber; private Encrypter encrypter; private BlockingCollection<string> paraCardNumberList; public
public class HashCompare
{
private string encryptedCardNumber;
private Encrypter encrypter;
private BlockingCollection<string> paraCardNumberList;
public string Compare(string hash)
{
bool exists = Lookup.hashExists(hash);
if (exists)
{
string unencryptedCardNumber = Lookup.GetUnencryptedCardNumber(hash);
return unencryptedCardNumber;
}
return null;
}
public BlockingCollection<string> PLCompareAll()
{
paraCardNumberList = new BlockingCollection<string>();
Parallel.For(100000, 999999, i =>
{
encrypter = new Encrypter();
encryptedCardNumber = encrypter.EncryptCardNumber(i.ToString());
var result = Compare(encryptedCardNumber);
if (result != null)
{
paraCardNumberList.Add(result);
}
});
paraCardNumberList.CompleteAdding();
return paraCardNumberList;
}
}
公共类HashCompare
{
私有字符串加密卡号;
专用加密机;
私人封锁收集助理卡号码列表;
公共字符串比较(字符串哈希)
{
bool exists=Lookup.hashExists(散列);
如果(存在)
{
string unencryptedCardNumber=Lookup.GetUnencryptedCardNumber(哈希);
返回未加密的卡号;
}
返回null;
}
公共封锁收集PLCompareAll()
{
paraCardNumberList=新建BlockingCollection();
平行。对于(100000,999999,i=>
{
encrypter=新的加密程序();
encryptedCardNumber=encrypter.EncryptCardNumber(i.ToString());
var结果=比较(加密卡号);
如果(结果!=null)
{
paraCardNumberList.Add(结果);
}
});
paraCardNumberList.CompleteAdding();
返回paraCardNumberList;
}
}
调用encrypter.EncryptCardNumber(似乎在returnValue.ToString()上)时随机发生错误
私有StringBuilder返回值
公共字符串加密卡号(字符串str)
{
尝试
{
var sha1=sha1.Create();
byte[]hashData=sha1.ComputeHash(Encoding.Default.GetBytes(str));
returnValue=新的StringBuilder();
for(int i=0;i
我有两个问题:
EncryptCardNumber
调用中都使用了相同的StringBuilder
实例。当一个线程执行.ToString()
而另一个线程尝试追加更多字符时,您会遇到争用条件,这并不奇怪
我猜您实际上并不打算让所有这些线程都覆盖并附加到彼此的StringBuilder实例。尝试将对象声明为局部变量,而不是该类上的字段。同样的原理可能也适用于其他变量,如encrypter
对于您的BlockingCollection
,这可能是一个很好的方法,但我个人会选择一些更实用的方法:
return Enumerable.Range(100000, 999999)
.AsParallel() // One line to make this parallel
.Select(i => new Encrypter().EncryptCardNumber(i.ToString())
.Select(Compare)
.Where(hash => hash != null)
.ToList();
您的代码无法编译。请张贴真实的代码。编辑-希望这是好的!你说你在加密这张卡,但实际上你只是在对它进行哈希运算。而你散列的方式是非常不安全的。您应该使用
SecureString
而不是string
,并使用安全哈希,如bcrypt。太好了,非常感谢。很好地解释了,我已经对StringBuilder进行了更改,它工作起来很有魅力,现在我将实施您的其他建议。
return Enumerable.Range(100000, 999999)
.AsParallel() // One line to make this parallel
.Select(i => new Encrypter().EncryptCardNumber(i.ToString())
.Select(Compare)
.Where(hash => hash != null)
.ToList();