c# - 多线程不处理所有任务

标签 c# multithreading for-loop parallel-processing

我正在使用以下代码使用线程执行任务,在这里我尝试执行“dtTable”数据表中的所有记录。线程数有限为 2(即,当时只有两个线程/只允许执行)。问题是它没有执行数据表中所有可用的记录,它以不规则的方式执行数据。可能是什么问题..?提前致谢。

 public class Generator : IDisposable
 {
    public static int maxThreadCount = 2;
    public static int runningThreadCount = 0;

    public RunTask()
    {
       for (int ro = 0; ro <= dtTable.Rows.Count - 1; ro++)
       {
          if (maxThreadCount > runningThreadCount)
          {
            Thread atpthread = new Thread(delegate()
            {
            DoOperationMethod(dtTable.Rows[ro], Task, startDate, EndDate, dtTemplate);
            });
            atpthread.Start();
            runningThreadCount = runningThreadCount + 1;
            Mainthreads.Add(atpthread);
          }
          else
          {
            ro--;
          }
       }
  }

  public void DoOperationMethod(DataRow drAttachpoint, System.StrTaskItem Task, DateTime startDate, DateTime EndDate, DataTable dtTemplate)
    {
     //doing my Operation
     runningThreadCount = runningThreadCount-1; //Once Task done count will get reduce
    }

我正在使用 .net 3.5(仅供引用)。

最佳答案

问题是您在等待线程空闲时不断迭代数据表中的行。在任何情况下,这种多线程,即使它实际上是正确的(它不是),也是非常低效的——大部分时间可能都花在了启动新线程上。

尝试这样的事情:

Parallel
 .ForEach(dtTable.Rows.OfType<DataRow>(), row => DoOperationMethod(...))
 .WithDegreeOfParallelism(2);

编辑:

要弄清楚问题是如何产生的,您必须了解如何在匿名方法中捕获变量。您的 DoOperationMethod 调用未传递给您想要的数据行,因为 ro“变量”未被复制,而是被引用。因此,当循环中的 ro 发生变化时,它也会在您创建的线程中发生变化。

这与您的代码非常线程不安全且效率低下这一事实不同:

  • 您实际上浪费了 三个 线程来完成工作 - 没有阻塞,您的循环只是不断地添加和减去 ro,这几乎完全是纯粹的 CPU 工作。这比在等待结果时简单地阻塞要浪费得多。
  • 您不能只从多个线程读取和写入静态字段并期望事情正常进行。实际上,您的代码很容易启动比您想要的更多的并行线程 - 甚至在 runningThread 最终成为 2 时死锁整个事情,而没有线程是运行。
  • 您不断启动新线程来执行看似微不足道的操作 - 我猜您的大部分工作要么受 I/O 限制,要么被一遍又一遍地创建新线程的成本所支配。
  • 我假设 Mainthreads 是某种类型的列表,我假设您还从 DoOperationMethod 方法修改它 - 同样,这可能会导致随机异常和意外结果.
  • 理论上,由于各种优化和缓存,检查 maxThreadCount > runningThreadCount 甚至可能永远不会被评估。实际上,在 x86 CPU 上的当前 .NET 上,对于像这样复杂的方法来说,这不太可能,但当您更新到 .NET 7.0 或其他版本时,这种情况可能会困扰您 :)

多线程很难。你真的不想猜测你的方式。至少,首先尝试了解基础知识 - http://www.albahari.com/threading/ .

关于c# - 多线程不处理所有任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30906679/

相关文章:

python - 使用 for 循环删除列表中的项目

c# - 在 C# 中的位置拆分字符串

c# - 为什么换行符不起作用?

c# - 匹配任何 IEnumerable<T> 的通用类型参数

c# - 为什么我的代码停止并且不返回异常?

c++ - 将 boost::asio::post 用于接受参数的函数

java - 我应该使用什么样的 map 界面?

python - 如何迭代/循环列表并引用前 (n-1) 个元素?

php - 打印一个图案以显示最多 5 行和 5 列的数字,例如 5 4 3 2 1 并在下一行 4 3 2 1 5 到第 5 行

javascript - 加载图像不显示