C# 在第二个窗体上使用BackgroundWorker运行方法

C# 在第二个窗体上使用BackgroundWorker运行方法,c#,.net,winforms,backgroundworker,C#,.net,Winforms,Backgroundworker,让我们假设我们有两种形式:MainForm和WaitingForm。我想将使用BackgroundWorker在后台运行的方法从MainForm传递到WaitingForm 现在,我是这样做的: MainForm.cs: public partial class MainForm: Form { private void btnImport_Click(object sender, EventArgs e) { var waitingFrm = new Waiti

让我们假设我们有两种形式:
MainForm
WaitingForm
。我想将使用
BackgroundWorker
在后台运行的方法从
MainForm
传递到
WaitingForm

现在,我是这样做的:

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()之后我的
长运行操作
未执行。

在您的等待表单中,我将执行以下操作:

public event DoWorkEventHandler DoWork {
    add { worker.DoWork += value; } 
    remove { worker.DoWork += value; }
}
(而不是get;set;属性)。 然后在主窗口中单击处理程序即可:

waitingFrm.DoWork += LongRunnignOperation;
对于已完成的处理程序也是如此。你的语法似乎太复杂了。这只是一种公开事件(在本例中是在waitingform上)和将事件处理程序传递给实际处理程序(在本例中是worker.DoWork)的干净方法。相当于

 waitingFrm.worker.DoWork += LongRunnignOperation;

这也行。

在您的等待表中,我会:

public event DoWorkEventHandler DoWork {
    add { worker.DoWork += value; } 
    remove { worker.DoWork += value; }
}
(而不是get;set;属性)。 然后在主窗口中单击处理程序即可:

waitingFrm.DoWork += LongRunnignOperation;
对于已完成的处理程序也是如此。你的语法似乎太复杂了。这只是一种公开事件(在本例中是在waitingform上)和将事件处理程序传递给实际处理程序(在本例中是worker.DoWork)的干净方法。相当于

 waitingFrm.worker.DoWork += LongRunnignOperation;
这也行

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

在这种情况下我会的

  • WaitingForm
  • Form1
    显示
    WaitingForm
    订阅该事件之前
  • 当必须运行长时间运行的操作时,
    WaitingForm
    引发一个事件,
    Form1
    获取它并
    Form1
    在其他线程中运行其方法
希望这有帮助

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

在这种情况下我会的

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

希望这有帮助

在这种情况下,您希望所有工作都在
MainForm
中进行,而
WaitingForm
似乎只是用户的一个显示。如果是这种情况,那么我只需将
BackgroundWorker
放在
main表单中,并使用事件调用
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;
  }
}

在这种情况下,您希望所有的工作都在
MainForm
中进行,而
WaitingForm
看起来只是用户的一个显示。如果是这种情况,那么我只需将
BackgroundWorker
放在
main表单中,并使用事件调用
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;
  }
}

所以,简单的答案是。您的代码不工作,因为mainform没有看到BackgroundWorker对象实例事件。而不是做:

    this.worker.DoWork += DoWork;
    this.worker.RunWorkerCompleted += OnWorkCompleted;
在WaitingForm-InitializeComponent()中,改为在mainForm中执行以下操作:

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

所以,简单的答案是。您的代码不工作,因为mainform没有看到BackgroundWorker对象实例事件。而不是做:

    this.worker.DoWork += DoWork;
    this.worker.RunWorkerCompleted += OnWorkCompleted;
在WaitingForm-InitializeComponent()中,改为在mainForm中执行以下操作:

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


为什么你需要后台工作人员在表单上?因为我想重用WaitingForm,让其他东西在后台运行。WaitingForm-Windows服务?@ChibuezeOpata:不,这是普通的WinForm,它不是任何服务。为什么构造函数名为
FrmWaiting
?为什么需要后台工作程序在表单上?因为我想重用WaitingForm以便在后台运行其他东西。WaitingForm-Windows服务?@ChibuezeOpata:不,它是普通的WinForm,它不是任何服务。为什么构造函数名为
FrmWaiting
?要么你缺少一个大括号,要么C#拥有在函数=)中声明函数的惊人能力。是的,但现在btnImport过程控制了:1)创建WaitingForm 2)创建BackgroundWorker,并将其连接到一个。“有点凌乱,”达里奥,我觉得这更简单。它显著降低了
WaitingForm
的复杂性,并将
BackgroundWorker
事件的使用限制在所需的最小范围内,无论您是否缺少大括号或C#具有在函数=)中声明函数的强大能力。是,但现在btnImport过程控制了:1)创建WaitingForm 2)创建BackgroundWorker,并将其连接到一个。“有点凌乱,”达里奥,我觉得这更简单。它显著降低了
WaitingForm
的复杂性,并将
BackgroundWorker
事件的使用限制在所需的最小范围内。我不想让我的员工公开,我认为最好隐藏这一点。重要的是你了解问题并解决它。。。如果您想使用这种方法,可以将其内部化。这是一个选择的问题。我不想公开我的员工,我认为最好隐藏这一点。重要的是你理解问题并解决它。。。如果您想使用这种方法,可以将其内部化。这是一个选择的问题。