16

私の .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 からメインに進行状況を表示できるようにします。

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 にアクセスすることは許可されていません。

誰かがこの問題を克服する方法を教えてもらえますか?

ps-この解決策を見つけましたが、理解できません。

4

3 に答える 3

33

変数として渡すことができます

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

しかし、最良の選択肢は、あなたが割り当てることができるeventであると思います。testClassForm

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;
    }
} 
于 2013-02-14T09:39:27.073 に答える
1

私はちょうどこれと同じ問題を抱えており (私の長時間実行されるプロセスはデータベースの復元です)、他のクラスでイベントを発生させることで同様の方法で解決しましたが、そのイベントのサブスクライバーを 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

フォームが予期せず閉じた場合に問題を引き起こす可能性があると思いますか?

于 2016-04-12T11:02:30.207 に答える
-2

上記のコードにこれがありませんか?:

backgroundWorker1 = new BackgroundWorker();

backgroundWorker1.DoWork += 新しい DoWorkEventHandler(backgroundWorker1_DoWork);

于 2018-09-10T19:09:20.747 に答える