0

I have to deal with like 10 binary files, each larger than 100MB. I have written a single thread program using BinaryReader, and it worked well. I want to make it parallel by using

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
  }
  -------------
} );

enter image description here updating progressbar (owned by UI Thread) is the problem each thread has its own progressbar control instance, but they cannot touch it.

aihenry2980
  • 329
  • 2
  • 7
  • 18
  • 4
    What are the exceptions? What are you doing with the data you are reading in? – juharr Mar 04 '15 at 14:52
  • Hard to say what your problem is without seeing the exception, but you could try using [`File.Open(Files[i], FileMode.Open, FileAccess.Read, FileShare.Read)`](https://msdn.microsoft.com/en-us/library/y973b725%28v=vs.110%29.aspx) – dbc Mar 04 '15 at 15:00
  • @juharr I read the file to the end, and do not modify it. – aihenry2980 Mar 04 '15 at 15:39
  • @aihenry2980 OK, but what are you doing with the data you are reading. I assume something or what would be the point of reading it in the first place. I'm guessing the issue is not with creating `BinaryReader`s on separate threads that are reading different files, but in what you do with that data, like merging it into one data structure shared by the threads. But really no one can help you without knowing what the exceptions are. – juharr Mar 04 '15 at 15:41
  • @juharr After reading Files[i], I write the result to Result[i]. and merge them after Parallel.For is over. – aihenry2980 Mar 04 '15 at 15:43
  • 1
    Don't do that! `Result[]` is a shared data structure, and from the sounds of it owned the UI thread, causing your exception. Have each thread return its result value and have the UI thread create and populate the array from the results. – Pieter Geerkens Mar 04 '15 at 15:47
  • 1
    In other words, it is always better that threads should only write to the data structures they own. Other patttersn require additional synchronization. – Pieter Geerkens Mar 04 '15 at 15:49
  • @PieterGeerkens Ok I will try to protect Result[] and test tmr. – aihenry2980 Mar 04 '15 at 15:52
  • Please improve this question by providing specific details of the exception -- type, message, and full stack trace -- along with [a good, _minimal_, _complete_ code example](http://stackoverflow.com/help/mcve) that reliably reproduces the problem. See http://stackoverflow.com/help/how-to-ask for other suggestions. – Peter Duniho Mar 04 '15 at 16:14

1 Answers1

0

You can not access control elements on a form from another thread than the main UI thread. You need to 'invoke' the function that does this job. Search for 'update controls from other than UI thread'.

Also, I suggest using BackgroundWorkers for this, because they habe a dedicated function for reporting progress to the main UI thread that controls the form:
https://msdn.microsoft.com/de-de/library/a3zbdb1t(v=vs.110).aspx

What data you pass to this function is up to you.

But there is one more thing for you to consider: are you reading the 10x 100MB from your hard disk drive? If yes, then you should keep the operations sequential!! Otherwise the hard disk will be the bottleneck and slow it all down instead of speeding it up, due to the positioning time of the read/write head when it jumps between the files.
This problem does not exist when reading the files from RAM (RAM disk) or SSD.

Tobias Knauss
  • 3,361
  • 1
  • 21
  • 45