I have an a windows form application that use one class (its name is Parser
)
this form has a button and when i click on the windows form application button it call one of the parser class method .
this method simply read text file line after line and write each line to separate file...
i would like to add a progress bar to the form in order to show the progress( it is a very large file )
any idea how to do that? I have in the Parse class 2 property one for the number of line in the file and the second how much lines already checked.
here is my button2_Click
function
private void button2_Click(object sender, EventArgs e)
{
if (this.textBox1 != null & this.textBox2 != null)
{
inst.init(this.textBox1.Text, this.textBox2.Text);
//this.progressBar1.Show();
inst.ParseTheFile();
System.Windows.Forms.MessageBox.Show("Parsing finish successfully");
}
}
You could do:
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem((obj) =>
{
var lines = File.ReadLines(@"D:\test.txt");
var count = lines.Count();
for(int i = 0; i < count; i++)
{
// some parse work
Invoke(new Action(() =>
{
progressBar1.Value = (i * 100) / count;
}));
}
});
}
In the example above, it simply creates a background thread in order not to block the UI thread, until the Invoke
method is called.
The Invoke
method is necessary, in order to manipulate with a Control
that the current thread isn't the owner of. It takes a delegate, and runs this delegate on the thread that owns the Control
.
You could even go as far, as making the foreach
loop parallel, if it's a time consuming task to parse the lines. An example:
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem((obj) =>
{
var lines = File.ReadLines(@"D:\test.txt");
var count = lines.Count();
Parallel.For(0, count, i =>
{
// some parse work
Invoke(new Action(() =>
{
progressBar1.Value = (i * 100) / count;
}));
});
});
}
normaly you should go on and write some on what you allready tried.
As I think you are more on the *begining" side I would advise looking into the BackgroundWorker and its ProgressChanged event / system (Here is a intro to it).
Of course you have to move your ParseTheFile-code into this.
For more advanced stuff there are a few options:
- add a parameter to the
ParseTheFile
(for example a Action) that is used to set the progress
- return a IObservable from your
ParseTheFile
that indicates the progress
- use some static service
ParseTheFile
is using to indicate the progress (not adviced)
- ... (I'm sure other poeple will find a lot more options)
(Please not that most of this options require to use Control.Invoke to get back to your UI-Thread for setting progress-bars value if you use another thread - and I would advise you using another thread if the file is that big)
For starter I would go with the backgroundworker - IMHO it's fine if you don't want to go SOLID (desing patterns/priciples) on your first run ;)
Just use Math to Calculate Percentage
Like :
//While Reading
NumOfLines++;
int Percentage = (NumOfLines * 100) / TotalLines ;
ProgressBar.Value = Percentage;
And probably put int.ParseTheFile(); into a Background Worker and/or within a Thread.