简体   繁体   English

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

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

I have 2 form (formA & formB) in my project c#, i want to run some process in backgroundworker when i click a button in formA. 我的项目C#中有2个表单(formA和formB),当我单击formA中的按钮时,我想在backgroundworker中运行某些进程。

can i update from backgroundworker to label in formB? 我可以从backgroundworker更新到formB中的标签吗? here's the code in formA 这是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();
    }

and heres code in formB 和继承人在formB中的代码

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

thankyou for attention.. 感谢您的关注..

You can change your code like below and it'll work fine. 您可以像下面那样更改代码,即可正常工作。

  1. Change perbaharuiStimulus code to 将perbaharuiStimulus代码更改为

     lbStimulus.Text = stimulus; 
  2. Change WorkerReportsProgress to True WorkerReportsProgress更改为True

  3. Change backgroundWorker1_DoWork to below 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. Add the backgroundWorker1_ProgressChanged event and put below code in it 添加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(); } 

I hope this help you! 希望对您有所帮助!

You can update a label in any form from a background worker using Invoke(...) like you did it. 您可以像执行此操作一样,使用Invoke(...)从后台工作程序以任何形式更新标签。 (Assuming stimulus is a field). (假设刺激是一个领域)。 It is enough to call Invoke once. 调用一次Invoke就足够了。 Stimulus.Invoke executes the delegate on the control thread of the stimulus form. Stimulus.Invoke在刺激形式的控制线程上执行委托。 So you can decide, whee you dispatch the thread. 因此,您可以在调度线程时决定。 I'd recommend to do this in perbarauiStimulus , since that would reduce the chance that someone forgets to dispatch the call. 我建议在perbarauiStimulus执行此perbarauiStimulus ,因为这样可以减少有人忘记分派呼叫的机会。

But there is one potential issues with your code: 但是您的代码存在一个潜在的问题:

Don't use exact comparison for elapsed time. 不要对经过的时间使用精确的比较。 Prefer using '>='. 优先使用'> ='。 Since you are dealing with seconds this will rarely be an actual problem, but it may result in an infinite loop. 由于您要处理的秒数很少会成为实际问题,但可能会导致无限循环。

If stimulus isn't a field you have to create an instance of Stimulus outside of the background worker, because if you create it inside the worker Method, the form will run its message loop on the background workers thread. 如果stimulus不是一个字段,则必须在后台工作程序之外创建一个Stimulus实例,因为如果您在worker方法内创建它,则表单将在后台工作程序线程上运行其消息循环。 This eliminates the use of a background worker since the operation runs now synchronously from sytimulus view. 由于该操作现在从同步视图中同步运行,因此无需使用后台工作程序。

You shouldn't be creating the form in the background thread. 您不应该在后台线程中创建表单。 Doing so will assign the form to that thread instead of the UI thread, meaning the form is now on a different thread than the message pump. 这样做会将表单分配给线程而不是UI线程,这意味着该表单现在与消息泵不在同一线程上。

What you can do to fix this is to invoke the instantiation and viewing of the form on the UI thread, then your following Invoke calls should work. 解决此问题的方法是在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...

Apart from that you're doing everything correctly. 除此之外,您可以正确地完成所有操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM