C# 4.0 数据表上的并行ForEach
我想使用新的Parallel.ForEach函数在datatable中循环并对每一行执行操作。我正在尝试转换以下代码:C# 4.0 数据表上的并行ForEach,c#-4.0,parallel-processing,C# 4.0,Parallel Processing,我想使用新的Parallel.ForEach函数在datatable中循环并对每一行执行操作。我正在尝试转换以下代码: foreach(DataRow drow in dt.Rows) { ... Do Stuff ... } 根据本守则: System.Threading.Tasks.Parallel.ForEach(dt.Rows, drow =>
foreach(DataRow drow in dt.Rows)
{
...
Do Stuff
...
}
根据本守则:
System.Threading.Tasks.Parallel.ForEach(dt.Rows, drow =>
{
...
Do Stuff
...
});
当我运行新代码时,会出现以下错误:
无法从用法推断方法“System.Threading.Tasks.Parallel.ForEach(System.Collections.Generic.IEnumerable,System.Action)”的类型参数。尝试显式指定类型参数
正确的语法是什么?
DataTable.Rows
返回一个DataRowCollection
,它只实现IEnumerable
,而不是IEnumerable
。使用DataTable
(来自DataTableExtensions
)上的扩展方法:
Parallel.ForEach()要求第一个参数为IEnumerable类型。不支持DataTable.Rows,但可以使用AsEnumerable()扩展方法将其转换为一个。尝试:
... Parallel.ForEach(dt.AsEnumerable(), drow => ...
这比公认的答案要好,因为这不需要引用System.Data.DataSetExtensions:
Parallel.ForEach(dt.Rows.Cast<DataRow>(), dr =>
Parallel.ForEach(dt.Rows.Cast(),dr=>
要将ForEach与非泛型集合一起使用,可以使用Cast扩展方法将集合转换为泛型集合,如本例所示。我必须修改Jon Skeet的答案才能使其正常工作
Parallel.ForEach(dt.AsEnumerable<DataRowType>(), drow => {
drow.SomeCol = "";
});
Parallel.ForEach(dt.AsEnumerable(),drow=>{
drow.SomeCol=“”;
});
通过这种方式,我们可以对数据表使用Parallel.ForEach
DataTable dtTest = new DataTable();
dtTest.Columns.Add("ID",typeof(int));
dtTest.Columns.Add("Name", typeof(string));
dtTest.Columns.Add("Salary", typeof(int));
DataRow dr = dtTest.NewRow();
dr["ID"] = 1;
dr["Name"] = "Rom";
dr["Salary"] = "2000";
dtTest.Rows.Add(dr);
dr = dtTest.NewRow();
dr["ID"] = 2;
dr["Name"] = "David";
dr["Salary"] = "5000";
dtTest.Rows.Add(dr);
dr = dtTest.NewRow();
dr["ID"] = 3;
dr["Name"] = "Samy";
dr["Salary"] = "1200";
dtTest.Rows.Add(dr);
Parallel.ForEach(dtTest.AsEnumerable(), drow =>
{
MessageBox.Show("ID " + drow.Field<int>("ID") + " " + drow.Field<string>("Name") + " " + drow.Field<int>("Salary"));
});
DataTable dtTest=newdatatable();
添加(“ID”,typeof(int));
dtTest.Columns.Add(“Name”,typeof(string));
dtTest.Columns.Add(“工资”,typeof(int));
DataRow dr=dtTest.NewRow();
dr[“ID”]=1;
dr[“Name”]=“Rom”;
dr[“工资”]=“2000”;
dtTest.Rows.Add(dr);
dr=dtTest.NewRow();
dr[“ID”]=2;
博士[“姓名”]=“大卫”;
dr[“工资”]=“5000”;
dtTest.Rows.Add(dr);
dr=dtTest.NewRow();
dr[“ID”]=3;
dr[“Name”]=“Samy”;
dr[“工资”]=“1200”;
dtTest.Rows.Add(dr);
Parallel.ForEach(dtTest.AsEnumerable(),drow=>
{
MessageBox.Show(“ID”+drow.Field(“ID”)+“”+drow.Field(“Name”)+“”+drow.Field(“薪水”);
});
D'oh!击出重拳(仅几秒钟)!对于实现IEnumerable的其他集合(如TreeNodeCollection),是否可以使用相同的扩展?还是我必须自己创建此扩展?@Scott:您必须自己编写—否则,如果您明白我的意思,它将不知道返回哪种类型的IEnumerable
。请确保引用System.Data.DatasetExtensions注意到DataTable不是线程安全的。您可能会遇到“内部索引已损坏”错误。但请记住以下内容:“如果无法将元素强制转换为类型TResult,则此方法将引发异常。若要仅获取可强制转换为类型TResult的元素,请使用OfType方法而不是强制转换(不可数)。”
DataTable dtTest = new DataTable();
dtTest.Columns.Add("ID",typeof(int));
dtTest.Columns.Add("Name", typeof(string));
dtTest.Columns.Add("Salary", typeof(int));
DataRow dr = dtTest.NewRow();
dr["ID"] = 1;
dr["Name"] = "Rom";
dr["Salary"] = "2000";
dtTest.Rows.Add(dr);
dr = dtTest.NewRow();
dr["ID"] = 2;
dr["Name"] = "David";
dr["Salary"] = "5000";
dtTest.Rows.Add(dr);
dr = dtTest.NewRow();
dr["ID"] = 3;
dr["Name"] = "Samy";
dr["Salary"] = "1200";
dtTest.Rows.Add(dr);
Parallel.ForEach(dtTest.AsEnumerable(), drow =>
{
MessageBox.Show("ID " + drow.Field<int>("ID") + " " + drow.Field<string>("Name") + " " + drow.Field<int>("Salary"));
});