My user wishes to see visual proof that their app is processing files. I've never used a ProgressBar before and I'm trying to get a test to work before I 'muddy-up' my production app.
I've gotten to the point that I can get the Value to display as each record in a file is read; however, when it gets to the final record it displays the following exception:
Value of '1894' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'.
Parameter name: Value
I know what the problem is (there's 1893 records in my test file), I just don't know how to fix it. I've tried to set the record count to it's value +1 (this.thisProgressBar.Maximum = Convert.ToInt32 ( m_strInputFile.Length / 1024 + 1 ); ), but still get the same exception.
Any assistance on this would really be appreciated.
private void OpenInputFile ( )
{
string strInText="";
OpenFileDialog dlgOpenFile = new OpenFileDialog ( );
dlgOpenFile.InitialDirectory = m_strInitDir;
dlgOpenFile.Filter = m_strInitFileFilter;
dlgOpenFile.FilterIndex = 1;
dlgOpenFile.RestoreDirectory = true;
if ( dlgOpenFile.ShowDialog ( ) == DialogResult.Cancel )
{
this.buttonStartDisplay.Enabled = true;
dlgOpenFile.Dispose ( );
}
else
{
m_strInFilePath = dlgOpenFile.FileName;
FileInfo m_strInputFile = new FileInfo ( m_strInFilePath );
sr_FileReader = m_strInputFile.OpenText ( );
this.thisProgressBar.Maximum = Convert.ToInt32 ( m_strInputFile.Length / 1024 );
try
{
using ( sr_FileReader )
{
while ( ( strInText = sr_FileReader.ReadLine ( ) ) != null )
{
this.thisProgressBar.Value += 1;
}
}
}
catch ( Exception ex )
{
MessageBox.Show ( "An exception has occured while\n " +
"pre-processing this file. \n\n" +
ex.Message + "\n\n",
"Exception Error",
MessageBoxButtons.OK );
}
}
}

ProgressBar Dilemma
Kidsauth
Well, the smaller of the files just took about 3 minutes to load into Notepad with 1,501,203 lines. To me, I don't think my user's would accept that. Now, If I load the file twice just to get a line count, that may pose a situation.
Rhubarb
AlfonsAberg
So in other words, ProgressBars and other visual controls similar to it are there to give users the "warm-fuzzies". I always used a Label and displayed a running count that was updated as the lines were read; always worked for me.
Rhubarb
ravindra_pn
Doesn't sound like too much. But then again, that depends on the system on which the application is running. You can try reading files into memory anyway and see how the system behaves...
Andrej
RamyaP
Also, try calling your OpenFileDialog with using statement, which will take care of proper disposing for you, like in this example:
using ( OpenFileDialog dlgOpenFile = new OpenFileDialog ( ))
{
dlgOpenFile.InitialDirectory = m_strInitDir;
dlgOpenFile.Filter = m_strInitFileFilter;
dlgOpenFile.FilterIndex = 1;
dlgOpenFile.RestoreDirectory = true;
if ( dlgOpenFile.ShowDialog ( ) == DialogResult.Cancel )
{
this.buttonStartDisplay.Enabled = true;
return;
}
m_strInFilePath = dlgOpenFile.FileName;
...
}
Manash
I obviously misread the number... So you're working with 900 Megs text files Not bad :) And yes, reading all this at once is out of the question...
And talking about the warm-fuzzies... have you seen how progress bar looks in Vista
Andrej
knvdssr
I'm still not sure what the record is in your case. Is it a line If it's fixed length record, you can just calculate the number of records - fileLength / recordLength.
Andrej
Wil Burton
These files are huge. I tried to perform a simple Open/Read on one, no data processing involved and it took about 5 minutes just to read the file!
Never had the pleasure of a Vista experience. I don't think my office will go that route, we were still using Windows 98 up until 2003 when we finally moved to XP!
Rhubarb
Charles Tam
mrLarry1975
You should replace this.thisProgressBar.Value += 1; with this.thisProgressBar.Value = sr_FileReader.BaseStream.Position / 1024;
Also, after you get it working normally you should manually check whether the new value will be greater than the max, and if so set it to the 100% value.
Ljhopkins
topographicaltales
Generally though, there is no reason to have progress bars be perfect, as they usually just serve as a visual representation that the process is running and of how much time is left.
Blast
Ok, thanks Andrej. Unfortunatly, several of the files I read/process are extremely large (from 300,000 to 900,000 KB). It looks like I may just have to display a 'relative' progress. But then, there's the problem of setting a valid Maximum value. Too low and it'll pass an exception. Ahhh, C# is so much fun!
Greg
'Rhubarb'
Richard1_1970
As I'm seeing it, you're calculating your Max value by converting your file's length into kilobytes, but you're reading the file line by line. This would work only in case when each line is exactly 1 kb in length (including new line characters)...
I'm not sure what a "record" in your case is, but if it is a line then you'll have to find out the number of lines before you start processing the file.
For a quick and dirty workaround, you can start with something like in this piece of code and see what's happening:
while ( ( strInText = sr_FileReader.ReadLine ( ) ) != null )
{
int record = this.thisProgressBar.Value += 1;
if (record > this.thisProgressBar.Maximum)
{
record = this.thisProgressBar.Maximum;
}
this.thisProgressBar.Value = record;
}
Andrej
IHan
It's difficult to determine the number of lines, contained in a file, without reading it through... So, if we're not talking *very* large files, you can read the whole content of a file at once and create a line array:
string[] lines = File.ReadAllLines(path);int recordCount = lines.Length;
Then, instead of seeking through file stream, run through string array and increment the progress bar. Remember, doing this, you're reading the whole file into the memory, so processing large files might not work as expected...
Andrej