Это хорошая идея, чтобы не связывать форму тесно с модулем. Один из способов сделать это - определить интерфейс, который реализует форма, и заставить модуль принимать такой интерфейс в качестве параметра. Я приведу пример с некоторым кодом. Начнем с интерфейса:
public interface IDataReceiver
{
void SetData(string data);
}
В моем примере я использую string
для данных, но это может быть любой тип, который вам нужно использовать. Затем мы реализуем этот интерфейс в виде:
public partial class Form1 : Form, IDataReceiver
{
private void Button_Click(object sender, EventArgs e)
{
// create a module intstance, passing this form as parameter
var module = new SomeModule(this);
module.DoSomeWork();
}
public void SetData(string data)
{
// use the data that is received
txtSomeTextBox.Text = data;
}
// the rest of the form code left out to keep it short
}
Наконец модуль с BackgroundWorker:
public class SomeModule
{
private BackgroundWorker _worker = new BackgroundWorker();
private IDataReceiver _receiver;
public SomeModule(IDataReceiver receiver)
{
_worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
_worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged);
_worker.WorkerReportsProgress = true;
_receiver = receiver;
}
void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
_receiver.SetData(e.UserState.ToString());
}
public void DoSomeWork()
{
// start the worker
_worker.RunWorkerAsync();
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// call method to pass data to receiver
_receiver.SetData(e.Result.ToString());
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
// do some work here
// assign the resulting data to e.Result
for (int i = 0; i < 10; i++)
{
_worker.ReportProgress(0, "some data " + i);
Thread.Sleep(250);
}
e.Result = "Finished";
}
}
Таким образом, модуль никоим образом не зависит от того, как выглядит ваш класс формы (он даже не подозревает, что он общается с формой). В моем примере я вызываю _receiver.SetData
из обработчика событий RunWorkerCompleted
, но это также можно сделать из обработчика событий ReportProgress
.
Также обратите внимание, что форма является «движущей силой» здесь. Модуль не создает формы и не предпринимает никаких инициатив любого рода. Просто используется формой.