【问题标题】:Multitasking multiple Class Instances多任务处理多个类实例
【发布时间】:2014-01-20 12:19:00
【问题描述】:

今天我决定尝试多任务处理,看看与多线程处理相比我是否获得了性能提升。我特别感兴趣,因为我正在寻找一种简单的方法来返回值并使用 WaitAll 或 WaitAny 等功能。我的问题是我做错了什么,多任务多个实例的最佳方法是什么?

这是我使用线程的旧代码。 (工作中)

Thread[] threads = new Thread[5];
ScrapeFollowersIds[] scrapeClass = new ScrapeFollowersIds[5];
for (int i = 0; i < 5; i++)
{
  scrapeClass[i] = new ScrapeFollowersIds();
  threads[i] = new Thread(() => scrapeClass[i].ScrapeFollowers(cookie,proxy);
  threads[i].Start();
}

这是我的新解决方案。

每个任务都显示状态 = 故障,方法 {null},尚未计算结果 查看异常我得到 Inner Exception: Index was outside the bounds of the Array

Task<string>[] scrapeFollowers = new Task<string>[5];
ScrapeFollowersIds[] scrapeClass = new ScrapeFollowersIds[5];
for (int i = 0; i < 5; i++)
{
  scrapeClass[i] = new ScrapeFollowersIds();
  scrapeFollowers[i] = Task<string>.Factory.StartNew(() => 
                         scrapeClass[i].ScrapeFollowers(cookie, proxy);
}

我调用的方法是这样的

try
{  
  //Dosomething 
  return someString;
} 
catch
{
  return "";
}

【问题讨论】:

  • 你是closing over the loop variable,一个典型的错误。
  • 请阅读多任务与多线程的定义。维基百科是此类主题的整体初学者信息的合理来源。

标签: c# .net multithreading multitasking


【解决方案1】:

您正在关闭循环变量i。

两个程序中都存在这个错误。

由于定义要在另一个线程中运行的代码的 lambda 关闭了 i,并且 i 在代码实际运行之前最终(可能)被主线程更改。复制循环内的循环变量并关闭 那个。

话虽如此,您可以通过不创建所有任务都需要手动访问的外部数组来完全使用 TPL 来避免整个情况。这不是一种非常面向 TPL 的做事方式。而是让每个任务独立创建其结果,然后汇总结果:

var tasks = Enumerable.Range(0, 5)
    .Select(_ => Task.Run(() => CreateScrapeFollower(cookie, proxy)));

var results = Task.WhenAll(tasks);

【讨论】:

  • 但是我可以返回这样的字符串值吗?
  • @user3155276 当然可以。结果都将在results 变量中。
  • 我还是有点困惑。这会创建 5 个不同的类实例吗?因为我想使用 5 个任务和 5 个类实例。
  • @user3155276 大概CreateScrapeFollower 方法会创建一个类的实例然后使用它。
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多