簡體   English   中英

我如何使用Backgroundworker C#更改其他形式的標簽?

[英]How do i change label in another form with backgroundworker process c#?

我的項目C#中有2個表單(formA和formB),當我單擊formA中的按鈕時,我想在backgroundworker中運行某些進程。

我可以從backgroundworker更新到formB中的標簽嗎? 這是formA中的代碼

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

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Stimulus stimulus = new Stimulus();
        Stopwatch watch = new Stopwatch();
        stimulus.Show();
        stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus("+"); });
        watch.Start();
        do
        {

        } while (watch.Elapsed.Seconds != 2);
        watch.Restart();
        stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus("MAJU"); });
        do
        {

        } while (watch.Elapsed.Seconds != 6);
        watch.Restart();
        stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus(""); });
        do
        {

        } while (watch.Elapsed.Seconds != 2);
        watch.Stop();
        stimulus.Close();
    }

和繼承人在formB中的代碼

        public Stimulus()
    {
        InitializeComponent();
        FormBorderStyle = FormBorderStyle.None;
        WindowState = FormWindowState.Maximized;
    }
    public void perbaharuiStimulus(string stimulus)
    {
        this.Invoke((MethodInvoker)delegate
        {
            lbStimulus.Text = stimulus;
        });
    }

感謝您的關注..

您可以像下面那樣更改代碼,即可正常工作。

  1. 將perbaharuiStimulus代碼更改為

     lbStimulus.Text = stimulus; 
  2. WorkerReportsProgress更改為True

  3. backgroundWorker1_DoWork更改為以下

      Stimulus stimulus = new Stimulus(); Stopwatch watch = new Stopwatch(); backgroundWorker1.ReportProgress(1, stimulus); watch.Start(); do { } while (watch.Elapsed.Seconds != 2); watch.Restart(); backgroundWorker1.ReportProgress(2, stimulus); do { } while (watch.Elapsed.Seconds != 6); watch.Restart(); backgroundWorker1.ReportProgress(3, stimulus); do { } while (watch.Elapsed.Seconds != 2); watch.Stop(); stimulus.Invoke((MethodInvoker)delegate { stimulus.Close(); }); 
  4. 添加backgroundWorker1_ProgressChanged事件並將其放在下面的代碼中

     private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { Stimulus stimulus = ( Stimulus)e.UserState; if(e.ProgressPercentage==1) stimulus.perbaharuiStimulus("+"); if (e.ProgressPercentage == 2) stimulus.perbaharuiStimulus("MAJU"); if (e.ProgressPercentage == 3) stimulus.perbaharuiStimulus(""); stimulus.Show(); } 

希望對您有所幫助!

您可以像執行此操作一樣,使用Invoke(...)從后台工作程序以任何形式更新標簽。 (假設刺激是一個領域)。 調用一次Invoke就足夠了。 Stimulus.Invoke在刺激形式的控制線程上執行委托。 因此,您可以在調度線程時決定。 我建議在perbarauiStimulus執行此perbarauiStimulus ,因為這樣可以減少有人忘記分派呼叫的機會。

但是您的代碼存在一個潛在的問題:

不要對經過的時間使用精確的比較。 優先使用'> ='。 由於您要處理的秒數很少會成為實際問題,但可能會導致無限循環。

如果stimulus不是一個字段,則必須在后台工作程序之外創建一個Stimulus實例,因為如果您在worker方法內創建它,則表單將在后台工作程序線程上運行其消息循環。 由於該操作現在從同步視圖中同步運行,因此無需使用后台工作程序。

您不應該在后台線程中創建表單。 這樣做會將表單分配給線程而不是UI線程,這意味着該表單現在與消息泵不在同一線程上。

解決此問題的方法是在UI線程上調用實例化和窗體的查看,然后您隨后的Invoke調用應該可以工作。

Stimulus stimulus;

this.Invoke((MethodInvoker)delegate
{
    stimulus = new Stimulus();
    stimulus.Show();
});

//No need to invoke this since perbaharuiStimulus() calls Invoke() as well.
stimulus.perbaharuiStimulus("+");

//The rest of your code...

除此之外,您可以正確地完成所有操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM