3

我正在尝试使用 BackgroundWorker,并尝试根据事件通知我的主线程。这些东西对我来说都是新的,想问一下,如果我做得很好。

我通过以下方式简化了我的一个winforms问题:(它只有一个按钮,当我按下它时在另一个线程中计数到十)

public partial class Form1 : Form
{
    public void Subscribe(CountToTen c)
    {
        c.HandleWorkerEvent += new CountToTen.WorkerHandler(OtherThreadFinished);
    }
    private void OtherThreadFinished(CountToTen c, EventArgs e)
    {
        Debug.WriteLine("I'm ready !!!");
    }

    public Form1()
    {
        InitializeComponent();
    }

    private void btn_do_Click(object sender, EventArgs e)
    {
        CountToTen newThread = new CountToTen();
        Subscribe(newThread);
        newThread.StartCountingAndReportIfFinished();
    }
}

CountToTen 类:

public class CountToTen
{

    public event WorkerHandler HandleWorkerEvent;
    public EventArgs e;
    public delegate void WorkerHandler(CountToTen c, EventArgs e);
    public void StartCountingAndReportIfFinished()
    {
        BackgroundWorker worker = new BackgroundWorker();

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            for (int i = 1; i <= 10; i++)
            {
                Thread.Sleep(300);
                Debug.WriteLine("Counting :" + i.ToString());

            }
        };

        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs args)
            {
                Debug.WriteLine("Fromt Thread2 : I am finished!");
                if (HandleWorkerEvent != null)
                {
                    HandleWorkerEvent(this, e);
                }
            });

        worker.RunWorkerAsync();
        worker.Dispose();
    }
}

我试图在 BW 完成后创建一个事件,并在我的主窗体中订阅此事件。它工作正常,但是,我真的不明白这一行发生了什么:

worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs args)
            {
                Debug.WriteLine("Fromt Thread2 : I am finished!");
                if (HandleWorkerEvent != null)
                {
                    HandleWorkerEvent(this, e);
                }
            });

我不是在这里为我的 BW 创建一个事件,当它完成后,然后为主线程调用另一个?这不是矫枉过正吗?我也可以直接订阅 RunWorkerCompleteEventHandler 吗?

我这里有点困惑,请初学者赐教。谢谢

4

3 回答 3

2

这是对 BackgroundWorker 的 RunWorkerCompleted 事件的订阅。您可以使用匿名方法或命名方法来执行此操作。您也可以通过这种方式删除委托类型声明:

worker.RunWorkerCompleted += (o, args) => 
{
    // raise HandleWorkerEvent if there is any subscriber exists
    if (HandleWorkerEvent != null)    
        HandleWorkerEvent(this, e);

    worker.Dispose();
};

使用命名方法,这看起来像

worker.RunWorkerCompleted += Worker_RunWorkerCompleted;

处理程序:

void Worker_RunWorkerCompleted(object o, RunWorkerCompletedEventArgs args)
{
    if (HandleWorkerEvent != null)    
        HandleWorkerEvent(this, e);

    ((BackgroundWorker)o).Dispose();
}

顺便说一句,我认为最好有课,这只会数到十个逻辑。在表单上创建 BackgroundWorker,并在 DoWork 事件处理程序中使用此类。表单也会处理它的所有组件。

于 2013-01-18T12:12:42.597 回答
0

您可以直接订阅 BackgroundWorker 的 RunWorkerCompleted 事件,但这取决于您的业务逻辑和架构。

于 2013-01-18T11:58:22.923 回答
0
Am I not creating an event here for my BW, when it is finished,
 and then call the another for the main thread?

是的..您正在处理 CountToTen 类中的 BackgroundWorker 事件。显然,根据您的类架构,通过事件通知您的主窗体的唯一方法。

  Is it not overkill? Could I subscribe directly to the RunWorkerCompleteEventHandler
  as well? 

当然你可以..你的 BackgroundWorker 没有直接暴露给主窗体,否则你可以从那里订阅 RunWorkerCompletedEvent 本身。

注意: 您不必调用 Dispose()。它通过 Component 实现 IDisposable 接口。详情请看这里

更新

  • 替代方式

    public partial class Form1 : Form
    {
      private void btn_do_Click(object sender, EventArgs e)
      { 
        CountToTen obj= new CountToTen();
         obj.bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
         obj.bw.RunWorkerAsync();
       }
    
       void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){}       
    }
    class CountToTen 
    {
    public BackgroundWorker bw = new BackgroundWorker();
    public CountToTen()
    {
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    }
    
    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        //Do your Stuff
    }
    }
    
于 2013-01-18T12:22:25.137 回答