Как изменить метку в другой форме с помощью процесса backgroundworker c #? - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть 2 формы (formA и formB) в моем проекте c #, я хочу запустить какой-то процесс в backgroundworker, когда я нажимаю кнопку в formA.вот код в форме A

        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 ]

0 голосов
/ 09 сентября 2018

Вы не должны создавать форму в фоновом потоке. При этом форма будет этой нити вместо нити пользовательского интерфейса, то есть форма теперь находится в потоке, отличном от потока сообщений.

Что вы можете сделать, чтобы это исправить, - это вызвать создание экземпляра и просмотр формы в потоке пользовательского интерфейса, тогда ваши следующие 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...

Кроме того, вы все делаете правильно.

0 голосов
/ 09 сентября 2018

Вы можете изменить свой код, как показано ниже, и он будет работать нормально.

  1. Изменить код стимула perbaharui на

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

Надеюсь, это поможет вам!

0 голосов
/ 09 сентября 2018

Вы можете обновить метку в любой форме из фонового рабочего, используя Invoke(...), как вы это сделали. (Предполагая, что стимул - это поле). Достаточно один раз вызвать Invoke. Stimulus.Invoke выполняет делегат в управляющем потоке формы стимула. Таким образом, вы можете решить, куда вы отправляете нить. Я бы рекомендовал сделать это в perbarauiStimulus, так как это уменьшит вероятность того, что кто-то забудет отправить вызов.

Но есть одна потенциальная проблема с вашим кодом:

Не используйте точное сравнение за прошедшее время. Предпочитаю использовать «> =». Поскольку вы имеете дело с секундами, это редко будет реальной проблемой, но это может привести к бесконечному циклу.

Если stimulus не является полем, вы должны создать экземпляр Stimulus вне фонового рабочего, потому что, если вы создадите его в рабочем методе, форма будет запускать свое сообщение Цикл на фоне рабочего потока. Это исключает использование фонового работника, поскольку операция теперь выполняется синхронно из представления sytimulus.

...