【问题标题】:report progress backgroundworker from different class c#报告来自不同类c#的进度backgroundworker
【发布时间】:2013-02-14 09:11:12
【问题描述】:

在我的 .NET C# 项目中,我使用了“BackgroundWorker”来调用不同类中的方法。以下是我的主窗体的源代码

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        testClass t1 = new testClass();
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            t1.changevalue(1000);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label1.Text += Convert.ToString(e.ProgressPercentage);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }
    }

并在我的项目中名为“testClass.cs”的单独类文件中包含以下代码。我想从这个类向BackgroundWorker报告进度,这样我就可以从label1的main中显示进度。

class testClass
    {
        private int val;
        public int changevalue(int i)
        {
            for (int j = 0; j < 1000; j++)
            {
                val += i + j;
                //from here i need to preport the backgroundworker progress
                //eg; backgroundworker1.reportProgress(j);
            }
            return val;
        }
    } 

但我不允许从“testClass”访问 BackgroundWorker。

谁能告诉我如何克服这个问题?

p.s- 我找到了this solution,但我不明白。

【问题讨论】:

    标签: c# backgroundworker


    【解决方案1】:

    你可以把它作为一个变量传入

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        t1.changevalue(1000, sender as BackgroundWorker);
    }
    
    
    class testClass
    {
        private int val;
        public int changevalue(int i, BackgroundWorker bw)
        {
            for (int j = 0; j < 1000; j++)
            {
                val += i + j;
                bw.ReportProgress(i);
                //from here i need to preport the backgroundworker progress
                //eg; backgroundworker1.reportProgress(j);
            }
            return val;
        }
    } 
    

    但是我认为最好的选择是testClass 中的event,您的Form 可以分配给它。

    public partial class Form1 : Form
    {
        private BackgroundWorker backgroundWorker1;
        private testClass t1 = new testClass();
    
        public Form1()
        {
            InitializeComponent();
    
            // subscribe to your event
            t1.OnProgressUpdate += t1_OnProgressUpdate;
        }
    
        private void t1_OnProgressUpdate(int value)
        {
            // Its another thread so invoke back to UI thread
            base.Invoke((Action)delegate
            {
                label1.Text += Convert.ToString(value);
            });
        }
    
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            t1.changevalue(1000);
        }
    
        private void button1_Click_1(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }
    
    }
    
    class testClass
    {
        public delegate void ProgressUpdate(int value);
        public event ProgressUpdate OnProgressUpdate;
    
        private int val;
        public int changevalue(int i)
        {
            for (int j = 0; j < 1000; j++)
            {
                val += i + j;
    
                // Fire the event
                if (OnProgressUpdate != null)
                {
                    OnProgressUpdate(i);
                }
            }
            return val;
        }
    } 
    

    【讨论】:

    • 非常感谢@sa_ddam213 先生。这正是我想要的。你的代码就像魅力一样工作。干杯!!
    • 您的第二个解决方案看起来有点难以阅读。为什么你认为它比第一个更好?
    • @Nolonar ,好吧,第二个版本将BackgroundWorker 与逻辑类分开,不仅该类现在可以返回进度,无论它是否与BacgroundWorker 一起使用,您只需需要订阅“OnProgressUpdate”事件,就是这样。
    【解决方案2】:

    我刚刚遇到了同样的问题(我的长期运行过程是数据库还原),并通过在其他类中引发事件以类似的方式解决了它,但随后让我对该事件的订阅者充当包装到 backgroundWorker1.ReportProgress()。

    private void DBRestoreProgressHandler(DataAccess da, DataAccess.DatabaseRestoreEventArgs e)
        {
            backgroundWorker1.ReportProgress(e.RestoreProgress);
        }
    
    private void backgroundWorker1_ReportProgress(object sender, ProgressChangedEventArgs e)
        {
            someLabel.Text = e.ProgressPercentage.ToString();
        }
    

    这节省了不得不使用:

    base.Invoke((Action)delegate
    

    我认为如果表单意外关闭会导致问题?

    【讨论】:

      【解决方案3】:

      我在上面的代码中缺少这个吗?:

      backgroundWorker1 = new BackgroundWorker();

      backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);

      【讨论】:

      • 我不认为这有资格作为答案。你不觉得吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多