In my .NET C# project I have used a "BackgroundWorker" to call a method in a different class. The following is the source-code of my main form
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
testClass t1 = new testClass();
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
t1.changevalue(1000);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text += Convert.ToString(e.ProgressPercentage);
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
and have the following code in a separate class file named "testClass.cs" in my project. I want to report the progress to the BackgroundWorker from this class, so that I will be able to display the progress in the main from label1.
class testClass
{
private int val;
public int changevalue(int i)
{
for (int j = 0; j < 1000; j++)
{
val += i + j;
//from here i need to preport the backgroundworker progress
//eg; backgroundworker1.reportProgress(j);
}
return val;
}
}
but I am not allowed to access BackgroundWorker from the "testClass".
Can someone please tell how to overcome this problem?
p.s- I have found this solution, but I don't understand it.
BackgroundWorker makes the implementation of threads in Windows Forms. Intensive tasks need to be done on another thread so the UI does not freeze. It is necessary to post messages and update the user interface when the task is done.
You can send a parameter to the background operation using the RunWorkerAsync() method. You can receive this parameter by using the Argument property of the instance of DoWorkEventArgs in the DoWork event handler then you cast it to use it in the background operation.
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running.
A BackgroundWorker component executes code in a separate dedicated secondary thread. In this article, I will demonstrate how to use the BackgroundWorker component to execute a time-consuming process while the main thread is still available to the user interface.
You could just pass it in as a variable
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
t1.changevalue(1000, sender as BackgroundWorker);
}
class testClass
{
private int val;
public int changevalue(int i, BackgroundWorker bw)
{
for (int j = 0; j < 1000; j++)
{
val += i + j;
bw.ReportProgress(i);
//from here i need to preport the backgroundworker progress
//eg; backgroundworker1.reportProgress(j);
}
return val;
}
}
But I think the best option would be an event
in the testClass
that your Form
can assign to.
public partial class Form1 : Form
{
private BackgroundWorker backgroundWorker1;
private testClass t1 = new testClass();
public Form1()
{
InitializeComponent();
// subscribe to your event
t1.OnProgressUpdate += t1_OnProgressUpdate;
}
private void t1_OnProgressUpdate(int value)
{
// Its another thread so invoke back to UI thread
base.Invoke((Action)delegate
{
label1.Text += Convert.ToString(value);
});
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
t1.changevalue(1000);
}
private void button1_Click_1(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
class testClass
{
public delegate void ProgressUpdate(int value);
public event ProgressUpdate OnProgressUpdate;
private int val;
public int changevalue(int i)
{
for (int j = 0; j < 1000; j++)
{
val += i + j;
// Fire the event
if (OnProgressUpdate != null)
{
OnProgressUpdate(i);
}
}
return val;
}
}
I've just had this same issue (my long running process is a database restore), and solved it in a similar way by raising an event in the other class, but then had my subscriber to that event just act as a wrapper to backgroundWorker1.ReportProgress().
private void DBRestoreProgressHandler(DataAccess da, DataAccess.DatabaseRestoreEventArgs e)
{
backgroundWorker1.ReportProgress(e.RestoreProgress);
}
private void backgroundWorker1_ReportProgress(object sender, ProgressChangedEventArgs e)
{
someLabel.Text = e.ProgressPercentage.ToString();
}
This saved having to use:
base.Invoke((Action)delegate
Which I think can then cause problems if the form closes unexpectedly?
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