Parallel.ForEach 未按预期工作 C#
Parallel.ForEach is not working as expected C#
我正在将 ForEach 替换为 Parallel.ForEach。 ForEach 工作正常并给出预期结果,而 Parallel.ForEach 给出意外结果。
string[] ids= { };
string input="AA;AA;111;T#BB;BB;222;T#CC;CC;333;F";
string typeId, type, value;
typeId= type=value=string.Empty;
bool isValid = false;
if (input.Contains("#"))
{ ids = input.Split('#'); }
else
{ ids = new string[] { input };}
//using ForEach ,it's working fine,datas are inserted in DB table properly.
foreach (var id in ids)
{
if (id.Contains(";"))
{
var IdInfo = id.Split(';');
if (IdInfo[0] != null)
{
typeId = Info[0];
}
if (IdInfo.Length >= 2)
{ type = IdInfo[1]; }
if (IdInfo.Length >= 3)
{ value = IdInfo[2]; }
if (IdInfo.Length >= 4)
{ isValid = IdInfo[3]=="T" ? true:false; } // T=true
}
else
{
return;
}
DBInsertMethod("someuniqueId", typeId, type, value, isValid);
}
我用 Parrallel.ForEach
替换了相同的代码
Parallel.ForEach ( ids,(id)=>
{
if (id.Contains(";"))
{
var IdInfo = id.Split(';');
if (IdInfo[0] != null)
{
typeId = Info[0];
}
if (IdInfo.Length >= 2)
{ type = IdInfo[1]; }
if (IdInfo.Length >= 3)
{ value = IdInfo[2]; }
if (IdInfo.Length >= 4)
{ isValid = IdInfo[3]=="T" ? true:false; } // T=true
}
else
{
return;
}
DBInsertMethod("someuniqueId", typeId, type, value, isValid);
});
现在同一行在 table.Any 中插入了三次 suggestion/advise 感谢。
所以你有这些变量:
string typeId, type, value;
bool isValid;
如果我运行这个foreach,在任何时候typeId被访问一次。
foreach (var item in list)
{
typeId = item.id;
}
现在,如果我让它并行,在任何时候 typeId 都会被 N 个线程访问。 N 个线程可以在 任何 时间更新它。
Parallel.ForEach(list, item =>
{
typeId = item.id;
});
将您的临时变量移动到 ForEach 中,以便将它们限定为匿名函数:
Parallel.ForEach(list, item =>
{
string typeId, type, value;
bool isValid;
typeId = item.id;
});
实际上,即使 Paralle.Foreach 创建了多个线程来处理并行处理,一些变量也是在其范围之外声明的,因此它们是唯一的。
尝试在 lambda 中声明它们:
Parallel.ForEach ( ids,(id)=>
{
string typeId, type, value;
typeId= type=value=string.Empty;
bool isValid=false;
if (id.Contains(";"))
{
var IdInfo = id.Split(';');
if (IdInfo[0] != null)
{
typeId = Info[0];
}
if (IdInfo.Length >= 2)
{ type = IdInfo[1]; }
if (IdInfo.Length >= 3)
{ value = IdInfo[2]; }
if (IdInfo.Length >= 4)
{ isValid = IdInfo[3]=="T"; } // T=true
}
else
{
return;
}
DBInsertMethod("someuniqueId", typeId, type, value, isValid);
});
我正在将 ForEach 替换为 Parallel.ForEach。 ForEach 工作正常并给出预期结果,而 Parallel.ForEach 给出意外结果。
string[] ids= { };
string input="AA;AA;111;T#BB;BB;222;T#CC;CC;333;F";
string typeId, type, value;
typeId= type=value=string.Empty;
bool isValid = false;
if (input.Contains("#"))
{ ids = input.Split('#'); }
else
{ ids = new string[] { input };}
//using ForEach ,it's working fine,datas are inserted in DB table properly.
foreach (var id in ids)
{
if (id.Contains(";"))
{
var IdInfo = id.Split(';');
if (IdInfo[0] != null)
{
typeId = Info[0];
}
if (IdInfo.Length >= 2)
{ type = IdInfo[1]; }
if (IdInfo.Length >= 3)
{ value = IdInfo[2]; }
if (IdInfo.Length >= 4)
{ isValid = IdInfo[3]=="T" ? true:false; } // T=true
}
else
{
return;
}
DBInsertMethod("someuniqueId", typeId, type, value, isValid);
}
我用 Parrallel.ForEach
替换了相同的代码Parallel.ForEach ( ids,(id)=>
{
if (id.Contains(";"))
{
var IdInfo = id.Split(';');
if (IdInfo[0] != null)
{
typeId = Info[0];
}
if (IdInfo.Length >= 2)
{ type = IdInfo[1]; }
if (IdInfo.Length >= 3)
{ value = IdInfo[2]; }
if (IdInfo.Length >= 4)
{ isValid = IdInfo[3]=="T" ? true:false; } // T=true
}
else
{
return;
}
DBInsertMethod("someuniqueId", typeId, type, value, isValid);
});
现在同一行在 table.Any 中插入了三次 suggestion/advise 感谢。
所以你有这些变量:
string typeId, type, value;
bool isValid;
如果我运行这个foreach,在任何时候typeId被访问一次。
foreach (var item in list)
{
typeId = item.id;
}
现在,如果我让它并行,在任何时候 typeId 都会被 N 个线程访问。 N 个线程可以在 任何 时间更新它。
Parallel.ForEach(list, item =>
{
typeId = item.id;
});
将您的临时变量移动到 ForEach 中,以便将它们限定为匿名函数:
Parallel.ForEach(list, item =>
{
string typeId, type, value;
bool isValid;
typeId = item.id;
});
实际上,即使 Paralle.Foreach 创建了多个线程来处理并行处理,一些变量也是在其范围之外声明的,因此它们是唯一的。 尝试在 lambda 中声明它们:
Parallel.ForEach ( ids,(id)=>
{
string typeId, type, value;
typeId= type=value=string.Empty;
bool isValid=false;
if (id.Contains(";"))
{
var IdInfo = id.Split(';');
if (IdInfo[0] != null)
{
typeId = Info[0];
}
if (IdInfo.Length >= 2)
{ type = IdInfo[1]; }
if (IdInfo.Length >= 3)
{ value = IdInfo[2]; }
if (IdInfo.Length >= 4)
{ isValid = IdInfo[3]=="T"; } // T=true
}
else
{
return;
}
DBInsertMethod("someuniqueId", typeId, type, value, isValid);
});