I'm a newbie with multithreading. I have a winform that have a label and a progress bar.
I wanna show the processing result. Firstly, I use Application.DoEvents()
method. But, I find that the form is freezing.
Then I read some article about multithreading at MSDN.
Secondly, I use a BackgroundWorker to do it.
this.bwForm.DoWork += (o, arg) => { DoConvert(); };
this.bwForm.RunWorkerAsync();
The form doesn't freeze that I can drag/drog when processing. Unfortunately, it throws an InvalidOperationException. So I have to use this. Control.CheckForIllegalCrossThreadCalls = false;
I ensure that's not a final solution.
Do you have some suggestion to do so, Experts?
Edit: When I call listview throw InvalidOperationException. This code is in DoWork().
foreach (ListViewItem item in this.listView1.Items)
{
//........some operation
lbFilesCount.Text = string.Format("{0} files", listView1.Items.Count);
progressBar1.Value++;
}
Edit2: I use delegate and invoke in DoWork() and it don't throw exeption. But the form is freezing again. How to do it so the form could be droppable/drappable while processing?
The . NET Framework has full support for running multiple threads at once.
Win Form has been used to develop many applications. Because of its high age (born in 2003), WinForm was officially declared dead by Microsoft in 2014. However, Win Form is still alive and well.
Multithreading in C# is a process in which multiple threads work simultaneously. It is a process to achieve multitasking. It saves time because multiple tasks are being executed at a time. To create multithreaded application in C#, we need to use System.
You can only set progress bar user control properties from the UI thread (the WinForm one). The easiest way to do it with your BackgroundWorker is to use the ProgressChanged event:
private BackgroundWorker bwForm;
private ProgressBar progressBar;
In WinForm constructor:
this.progressBar = new ProgressBar();
this.progressBar.Maximum = 100;
this.bwForm = new BackgroundWorker();
this.bwForm.DoWork += new DoWorkEventHandler(this.BwForm_DoWork);
this.bwForm.ProgressChanged += new ProgressChangedEventHandler(this.BwForm_ProgressChanged);
this.bwForm.RunWorkerAsync();
...
void BwForm_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgw = sender as BackgroundWorker;
// Your DoConvert code here
// ...
int percent = 0;
bgw.ReportProgress(percent);
// ...
}
void BwForm_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar.Value = e.ProgressPercentage;
}
see here: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
EDIT
So I didn't understand your question, I thought it was about showing progress bar progression during work. If it's about result of work use e.Result in the BwForm_DoWork event. Add a new event handler for completed event and manage result:
this.bwForm.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.BwForm_RunWorkerCompleted);
...
private void BwForm_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
YourResultStruct result = e.Result as YourResultStruct;
if (e.Error != null && result != null)
{
// Handle result here
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With