为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 backgroundworker 进程 c# 以另一种形式更改标签?

如何使用 backgroundworker 进程 c# 以另一种形式更改标签?

C#
德玛西亚99 2022-01-09 15:48:42
我的项目c#中有2个表单(formA和formB),当我单击formA中的按钮时,我想在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();    }和表单B中的代码        public Stimulus()    {        InitializeComponent();        FormBorderStyle = FormBorderStyle.None;        WindowState = FormWindowState.Maximized;    }    public void perbaharuiStimulus(string stimulus)    {        this.Invoke((MethodInvoker)delegate        {            lbStimulus.Text = stimulus;        });    }感谢您的关注..
查看完整描述

3 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

您可以像下面这样更改您的代码,它会正常工作。


将 perbaharuiStimulus 代码更改为


lbStimulus.Text = stimulus;

更改WorkerReportsProgress为True


更改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(); });

添加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();

}

我希望这对你有帮助!


查看完整回答
反对 回复 2022-01-09
?
慕少森

TA贡献2019条经验 获得超9个赞

您可以Invoke(...)像您所做的那样使用后台工作人员以任何形式更新标签。(假设刺激是一个场)。调用一次 Invoke 就足够了。Stimulus.Invoke在激励表单的控制线程上执行委托。所以你可以决定,当你调度线程时。我建议在 中执行此操作perbarauiStimulus,因为这样可以减少有人忘记发送呼叫的机会。

但是您的代码存在一个潜在问题:

不要使用经过时间的精确比较。更喜欢使用'>='。由于您正在处理秒数,因此这很少会成为实际问题,但可能会导致无限循环。

如果stimulus不是字段,则必须在后台工作人员Stimulus 之外创建一个实例,因为如果您在工作人员方法内创建它,表单将在后台工作人员线程上运行其消息循环。这消除了后台工作人员的使用,因为该操作现在从 sytimulus 视图同步运行。


查看完整回答
反对 回复 2022-01-09
?
萧十郎

TA贡献1815条经验 获得超13个赞

您不应该在后台线程中创建表单。这样做会将表单分配给该线程而不是 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...

除此之外,您所做的一切都是正确的。


查看完整回答
反对 回复 2022-01-09
  • 3 回答
  • 0 关注
  • 210 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号