0

假设我们有两种形式:MainFormWaitingForm. 我想从 传递MainFormWaitingForm在后台运行的方法,使用BackgroundWorker.

现在,我正在这样做:

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();
    }
}

但是在waitingFrm.Run();LongRunningOperation没有被执行之后。

4

4 回答 4

1

在您的 WaitingForm 中,我会这样做:

public event DoWorkEventHandler DoWork {
    add { worker.DoWork += value; } 
    remove { worker.DoWork += value; }
}

(而不是 get;set; 属性)。然后在你的主窗口btnImport_Click处理程序中:

waitingFrm.DoWork += LongRunnignOperation;

对于已完成的处理程序也是如此。您的语法似乎过于复杂。这只是公开事件(在这种情况下是在您的等待表单上)和将事件处理程序传递给真正的处理程序(在这种情况下是 worker.DoWork)的一种干净的方式。它相当于

 waitingFrm.worker.DoWork += LongRunnignOperation;

这也可以。

于 2012-04-07T13:53:52.267 回答
1

我想从 MainForm 传递到 WaitingForm 使用 BackgroundWorker 在后台运行的方法

在这种情况下我会

  • 声明一个事件WaitingForm
  • Form1节目WaitingForm订阅该事件之前
  • 当必须运行长时间运行的操作时,会WaitingForm引发一个事件,Form1获取它并 Form1在其他线程中运行它的方法。

希望这可以帮助。

于 2012-04-07T13:56:34.073 回答
1

在这种特殊情况下,您希望所有工作都在其中发生,MainForm并且看起来WaitingForm只是为用户展示。如果是这种情况,那么我只需将其BackgroundWorker放入MainForm并使用该事件来调用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;
  }
}
于 2012-04-07T13:58:59.723 回答
1

所以,简单的答案是这样的。您的代码不起作用,因为主窗体没有看到BackgroundWorker 对象实例事件。而不是这样做:

    this.worker.DoWork += DoWork;
    this.worker.RunWorkerCompleted += OnWorkCompleted;

在 WaitingForm - InitializeComponent() 中,改为在 mainForm 中执行此操作,如下所示:

    waitingFrm.worker.DoWork += waitingFrm.DoWork;
    waitingFrm.worker.RunWorkerCompleted += waitingFrm.OnWorkCompleted;
于 2012-04-07T14:43:30.287 回答