【问题标题】:Can I use progressbar in parallel? (every thread reads a different file) [duplicate]我可以并行使用进度条吗? (每个线程读取不同的文件)[重复]
【发布时间】:2024-05-18 19:20:02
【问题描述】:

我必须处理大约 10 个二进制文件,每个文件都大于 100MB。 我使用 BinaryReader 编写了一个单线程程序,它运行良好。 我想通过使用使其并行

Parallel.For(0,10, i=>
{
  -------------
  BinaryReader BR = new BinaryReader(File.Open(Files[i], FileMode.Open));
  While (BR.BaseStream.Position < BR.BaseStream.Length)
  { 
      Uint64 a = BR.ReadUInt64(); 
      ProgressBar[i].Value = Convert.ToInt32( 10* BR.BaseStream.Position / BR.BaseStream.Length); //error
  }
  -------------
} );

更新进度条(由 UI 线程拥有)是问题 每个线程都有自己的进度条控件实例,但他们不能触摸它。

【问题讨论】:

  • 有哪些例外?你对正在读取的数据做了什么?
  • 很难说你的问题是没有看到异常,但你可以尝试使用File.Open(Files[i], FileMode.Open, FileAccess.Read, FileShare.Read)
  • @juharr 我把文件读到最后,不要修改。
  • 不要那样做! Result[] 是一个共享数据结构,从它的声音来看它拥有 UI 线程,导致你的异常。让每个线程返回其结果值,并让 UI 线程根据结果创建和填充数组。
  • 换句话说,线程最好只写入它们拥有的数据结构。其他模式需要额外的同步。

标签: c# multithreading parallel-processing streamreader binaryreader


【解决方案1】:

您不能从主 UI 线程以外的其他线程访问表单上的控制元素。您需要“调用”完成这项工作的函数。搜索'从非 UI 线程更新控件'

另外,我建议为此使用 BackgroundWorkers,因为它们有一个专门的函数用于向控制表单的主 UI 线程报告进度:
https://msdn.microsoft.com/de-de/library/a3zbdb1t(v=vs.110).aspx

传递给此函数的数据由您决定。

但您还需要考虑一件事:您是否正在从硬盘驱动器读取 10x 100MB 的数据?如果是,那么您应该保持操作顺序!否则硬盘将成为瓶颈,因为文件之间跳转时读写头的定位时间而导致速度变慢而不是加速。
从 RAM(RAM 磁盘)或 SSD 读取文件时不存在此问题。

【讨论】:

    最近更新 更多