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 个数据行。 我不认为我现在如何拥有它来实现这一点。

谢谢!

C# 方法名称 预期错误,使用参数化线程启动

如果你想让

这项工作按照你尝试的方式工作,你必须让你的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");
        }
    }