C# 方法名称 预期错误,使用参数化线程启动
本文关键字:参数 启动 线程 错误 方法 | 更新日期: 2023-09-27 18:30:29
我正在尝试线程化,而且相对较新。
我想做的只是在传入参数的不同类上调用 void。
for (int i = 0; i < 1; i++)
{
foreach (DataRow dtRow in urlTable.Rows)
{
Thread thread = new Thread(new ParameterizedThreadStart(MasterCrawlerClass.MasterCrawlBegin(dtRow)));
}
}
public static void MasterCrawlBegin(DataRow dtRow)
{
if (dtRow.ItemArray[0].ToString().Contains("$"))
{
linkGrabberwDates(dtRow.ItemArray[0].ToString(), "www");
}
else
{
NoDatesCarCrawler(dtRow.ItemArray[0].ToString(), "www");
}
}
此外,我的目的是让 4 个线程运行,而每个线程只传入 1 个数据行。 我不认为我现在如何拥有它来实现这一点。
谢谢!
如果你想让
这项工作按照你尝试的方式工作,你必须让你的MasterCrawlBegin
方法将object
作为其参数,然后传入对方法本身的引用:
Thread thread = new Thread(new ParameterizedThreadStart(MasterCrawlerClass.MasterCrawlBegin));
但是利用闭包和lambda函数比诉诸ParameterizedThreadStart类更容易。
Thread thread = new Thread(() => MasterCrawlerClass.MasterCrawlBegin(dtRow));
更新
在阅读了您对另一个答案的评论后,我认为您可能会从了解 .NET 4 的任务并行库和 PLINQ 中受益。你可以以一种非常优化的方式并行化整个集合,如下所示:
urlTable.Rows.Cast<DataRow>().AsParallel()
.ForAll(MasterCrawlerClass.MasterCrawlBegin);
这将使框架确定它认为应该使用多少线程。如果你想要更多的控制,有一些微调的方法,比如确保只使用四个并发线程:
urlTable.Rows.Cast<DataRow>().AsParallel().WithDegreeOfParallelism(4)
.ForAll(MasterCrawlerClass.MasterCrawlBegin);
为了轻松实现这一点,同样使用与数据行解析相关的内容,您可以只访问全局变量并避免将其作为参数传递。如果解析的意思是从DataRow
读取数据,那么您是安全的。如果需要写入,最好实现一些锁定/同步机制,即使您现在完全确定一个线程始终保留自己的行。
希望这有帮助。
这样的代码也应该工作:
for (int i = 0; i < 1; i++)
{
foreach (DataRow dtRow in urlTable.Rows)
{
Thread thread = new Thread(MasterCrawlerClass.MasterCrawlBegin);
thread.Start(dtRow);
}
}
public static void MasterCrawlBegin(object data)
{
var dtRow = (DataRow)data;
if (dtRow.ItemArray[0].ToString().Contains("$"))
{
linkGrabberwDates(dtRow.ItemArray[0].ToString(), "www");
}
else
{
NoDatesCarCrawler(dtRow.ItemArray[0].ToString(), "www");
}
}