【问题标题】:access backgroundworker from a public method从公共方法访问 backgroundworker
【发布时间】:2017-10-19 00:45:41
【问题描述】:

所以我有 form1,它有 backgroundworker(通过设计视图拖放)。 我可以让它在我需要的地方工作,但是我需要从公共方法中调用它。

在这个公共方法中

Utility.initpacks(object sender, EventArgs e,string formname)

所以我的DoWorkForm1

我form里面的公用程序做了一堆事情,然后那个函数需要再次使用Form1里面的后台worker!

我可以复制公共方法并放在方法引用的位置,一切都很好..但这违背了公共方法的目的,不是吗!?

任何想法都会非常感谢:)

编辑:

所以我目前的设置(没有一堆不重要的东西):

public partial class frmimportinstitutions : Form
    {
    private void btnNext_Click(object sender, EventArgs e)
         {
         Utility.initpacks(sender, e, this.FindForm().Name);
         }




    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //Do stuff

        }
}

public static class Utility
    {
public static void initpacks(object sender, EventArgs e,string formname)
        {
//I WANT TO USE THE BACKGROUND WORKER HERE
//Do a public method
//I want to stop the background worker here
}
}

更新(基于 cmets):

Michael cmets 刚刚提到将后台工作人员启动在一个公共方法中:

public void startplash(string starttext)
        {
            if (!backgroundWorker1.IsBusy)
            {
                splashtext = starttext;
                backgroundWorker1.RunWorkerAsync();
            }

        }

现在我想从另一个方法调用这个方法。为了做到这一点,其他方法(init packs)需要知道这个方法在哪里。 例如。

form1.startsplash("hello world")

所以现在我只需要将 Form1 信息发送到初始化包...

这样可以吗:

Initpacks(Form Owner)
{
Owner.startsplash("hello world")
}

另一个更新! 感谢 Michael,到目前为止我们有这个:

public static class Utility
{
    public static void RunWorkerOfForm1()
    {
        var target = (Form1)Application.OpenForms.OfType<Form1>().FirstOrDefault();
        target?.RunWorker();
    }
}

现在我需要让它与不同的表格一起使用。我没有尝试过下面的方法,但这是我接下来要尝试的方法。如果我错了,请纠正我:

public static class Utility
{
    public static void RunWorkerOfForm1(Form owner)
    {
        var target = (owner)Application.OpenForms.OfType<owner>().FirstOrDefault();
        target?.RunWorker();
    }
}

最终答案(根据勾选的答案)-但使用我的代码:

public partial class frmholidaypacks : Form, IWorker
    {
private void btnextrapacks_Click(object sender, EventArgs e)
        {
         Utility.futurepacks<frmholidaypacks>(sender, e, pxid);
         }
     }

public interface IWorker
    {
        void startplash(string starttext);

    }

public void startplash(string starttext)
        {
            if (!backgroundWorker1.IsBusy)
            {
                splashtext = starttext;
                backgroundWorker1.RunWorkerAsync();
            }

        }

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //Doing work.  Using Splashtext string.

        }

public static void futurepacks<T>(object sender, EventArgs e, int pxid) where T : IWorker
        {
 var target = (T)Application.OpenForms.OfType<T>().FirstOrDefault();
            target?.startplash("Creating future packs");
        }

100% 感谢 Michael 和我一起工作!

【问题讨论】:

  • 我可以只在方法使用的参数中(Backgroundworker BGW)..? BGW.runasync() 会在其他表单上运行该后台工作程序的 dowork 部分吗?
  • 我真的不明白你想做什么,但是如果你想从一个不属于Form的外部方法启动BackgroundWorker,那么没有那么多方法可以做到: 1) 使BackgroundWorker 成为该表单的公共成员(错误) 2) 向运行backgroundWorker.RunAsync 的表单添加一个公共方法 - 请务必检查BackgroundWorkerBusy 状态。两种变体都可以/应该用一些接口抽象出来。
  • 好的,谢谢迈克尔,我正在研究第二个选项。我现在以这种形式在公共方法中拥有 backgroundworker.runasync,但是我如何将它传递给另一个公共方法,例如。将表单对象作为所有者发送给方法作为参数?
  • 第三种方法:在主窗体中定义一个(作业)队列。定义用于添加作业的公共方法。在您的BackgroundWorker 中运行一个无限循环,检查每次迭代的队列,如果没有作业存在则休眠一段时间,如果有需要处理的内容则提取并处理作业。添加null 或特定对象并在BackgroundWorker 中检查该对象是否要退出处理...对于您的情况可能有点多...
  • 用您的 option2 方法 michael 更新了我的问题,感谢您的帮助

标签: c# backgroundworker


【解决方案1】:

已编辑!

好的,现在我明白了。您要运行的每个表单都必须实现IWorker 接口。然后将具体的Form 传递给RunWorker 函数以用作通用参数。 where 子句只允许实现 IWorker 接口 - 它(当前)不限于 Form-instances。

public partial class Form2 : Form, IWorker
{
    public Form2()
    {
        InitializeComponent();
    }

    public void RunWorker()
    {
        if (backgroundWorker1.IsBusy) return;
        backgroundWorker1.RunWorkerAsync();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        UtilityX.RunWorker<Form2>();
    }
}

public static class UtilityX
{
    public static void RunWorker<T>() where T : IWorker
    {
        var target = (T)Application.OpenForms.OfType<T>().FirstOrDefault();
        target?.RunWorker();
    }
}

public interface IWorker
{
    void RunWorker();
}

【讨论】:

  • 谢谢迈克尔,差不多了。在你把它放在那里之前,我得到了你写的东西,我的最后一个问题是如果 form2 和 form1 现在都需要访问这个 RunWorkerOfForm1。例如。 RunworkerofFORM。因为重点是我有一个工作在 3 个不同的表单上,每个表单都需要根据调用 initpacks 方法的表单来运行
  • @GlennAngel 上面的代码应该可以实现您想要的。如果另一个表单调用RunWorkerOfForm1 并且后台工作人员已经在运行,会发生什么?如果当前进程被取消,它应该等到当前运行完成还是......?
  • 不应该这样 (Form1)Application.OpenForms.OfType().FirstOrDefault();是 (Form2)Application.OpenForms.OfType().FirstOrDefault();
  • 在我的示例中,BackgroundWorker 是 Form1 的一部分...在您的情况下,它应该是 Application.OpenForms.OfType&lt;frmimportinstitutions&gt;().FirstOrDefault()
  • 这不是我的意思。您应该阅读一些有关什么是接口以及如何实现它们的信息。基本上,接口定义了 public 方法和/或属性。 “想要”实现接口的类必须定义与接口完全相同的方法和属性。要实现接口,请将接口名称与类定义放在同一行,如下所示:public class MyForm: Form, IWorker。这会强制 MyForm 类提供接口中定义的方法。
【解决方案2】:

您是否尝试过使用静态方法, 如果你也想在多个地方使用它,你可以把你的代码放在一个静态方法中。

public class MyClass
    {
        public static void MyMethod()
        {
           //..
        }
    }

【讨论】:

  • 我认为使用 EventArgs 可能是更好的解决方案。
  • 嗨,Ehsan,感谢您的回复。我会在里面放什么??做功函数? utility.init 打包是一个公共静态方法,但在里面我需要调用 backgroundworker.RunAsync()
  • 你需要把用于后台数据逻辑的部分数据放到后台的DoWork方法中修改或读取数据
猜你喜欢
  • 1970-01-01
  • 2023-03-30
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 2012-12-09
  • 2011-02-11
相关资源
最近更新 更多