Reputation: 16721
Let's imagine that we have two Forms: MainForm
and WaitingForm
. I want to pass, from MainForm
, to the WaitingForm
the method to run in background using BackgroundWorker
.
Now, I'm doing things that way:
MainForm.cs
:
public partial class MainForm: Form
{
private void btnImport_Click(object sender, EventArgs e)
{
var waitingFrm = new WaitingForm();
waitingFrm.DoWork = (o, args) => this.LongRunningOperation(this, new DoWorkEventArgs("foo bar"));
waitingFrm.OnWorkCompleted = (o, args) => MessageBox.Show("Finished!");
waitingFrm.Show();
waitingFrm.Run(); // should execute LongRunningOperation, method below.
}
private void LongRunningOperation(object sender, DoWorkEventArgs e)
{
MessageBox.Show("Running long operation!....");
// some long running stuff here;
}
}
WaitingForm.cs
public partial class WaitingForm: Form
{
private BackgroundWorker worker = new BackgroundWorker();
public DoWorkEventHandler DoWork { get; set; }
public RunWorkerCompletedEventHandler OnWorkCompleted { get; set; }
public WaitingForm()
{
this.worker.DoWork += DoWork;
this.worker.RunWorkerCompleted += OnWorkCompleted;
InitializeComponent();
}
public void Run()
{
this.worker.RunWorkerAsync();
}
}
But after waitingFrm.Run();
my LongRunningOperation
is not executed.
Upvotes: 0
Views: 1699
Reputation: 10054
So, the simple answer is that. Your code is not working because the mainform is not seeing the BackgroundWorker object instance events. Instead of doing:
this.worker.DoWork += DoWork;
this.worker.RunWorkerCompleted += OnWorkCompleted;
in WaitingForm - InitializeComponent(), do this instead in mainForm like this:
waitingFrm.worker.DoWork += waitingFrm.DoWork;
waitingFrm.worker.RunWorkerCompleted += waitingFrm.OnWorkCompleted;
Upvotes: 1
Reputation: 754745
In this particular case you want all of the work to happen in MainForm
and it looks like WaitingForm
is just a display for the user. If that's the case then I would just put the BackgroundWorker
in the MainForm
and use the event to call into WaitingForm
public partial class MainForm: Form
{
private void btnImport_Click(object sender, EventArgs e) {
var waitingForm = new WaitingForm();
waitingForm.Show();
var worker = new BackgroundWorker();
worker.DoWork += (o, args) => this.LogRunningOperation(o, args);
worker.OnWorkComplete += (o, args) => {
waitingForm.Close();
worker.Dispose();
};
worker.RunWorkerAsync();
}
private void LongRunningOperation(object sender, DoWorkEventArgs e) {
MessageBox.Show("Running long operation!....");
// some long running stuff here;
}
}
Upvotes: 1
Reputation: 7705
In your WaitingForm I'd do:
public event DoWorkEventHandler DoWork {
add { worker.DoWork += value; }
remove { worker.DoWork += value; }
}
(Instead of the get;set; property).
And then in your main window btnImport_Click
handler just:
waitingFrm.DoWork += LongRunnignOperation;
And the same for completed handler. Your syntax seems overly complicated. This is just a clean way to expose an event (in this case on your waitingform) and the pass event handler through to the real handler (in this case worker.DoWork). It is equivalent to
waitingFrm.worker.DoWork += LongRunnignOperation;
which would do just as well.
Upvotes: 1
Reputation: 62246
I want to pass, from MainForm, to the WaitingForm the method to run in background using BackgroundWorker
I would in this case
WaitingForm
Form1
shows WaitingForm
subscribes to that event WaitingForm
raise an event, Form1
gets it and
Form1
runs its method in other thread. Hope this helps.
Upvotes: 1