Tengo 2 form (formA y formB) en mi proyecto c #, quiero ejecutar algún proceso en backgroundworker cuando hago clic en un botón en formA.

¿Puedo actualizar de backgroundworker a la etiqueta en el formulario B? Aquí está el código en 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();
    }

Y aquí está el código en forma B

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

Gracias por su atención..

-1
Fransiskus Cahyadi Putra 9 sep. 2018 a las 16:11

3 respuestas

La mejor respuesta

Puede cambiar su código como se muestra a continuación y funcionará bien.

  1. Cambiar el código de estímulo perbaharui a

    lbStimulus.Text = stimulus;
    
  2. Cambie WorkerReportsProgress a True

  3. Cambie backgroundWorker1_DoWork a continuación

        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. Agregue el evento backgroundWorker1_ProgressChanged y coloque el siguiente código en él

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

¡Espero que esto te ayude!

2
Visual Vincent 9 sep. 2018 a las 19:03

Puede actualizar una etiqueta en cualquier forma de un trabajador en segundo plano utilizando Invoke(...) como lo hizo. (Suponiendo que el estímulo es un campo). Es suficiente llamar a Invoke una vez. Stimulus.Invoke ejecuta el delegado en el hilo de control de la forma de estímulo. Para que pueda decidir, cuando despacha el hilo. Recomiendo hacer esto en perbarauiStimulus, ya que eso reduciría la posibilidad de que alguien se olvide de enviar la llamada.

Pero hay un problema potencial con su código:

No use la comparación exacta para el tiempo transcurrido. Prefiero usar '> ='. Como se trata de segundos, esto rara vez será un problema real, pero puede dar lugar a un bucle infinito.

Si stimulus no es un campo, debe crear una instancia de Stimulus fuera del trabajador en segundo plano, porque si lo crea dentro del Método trabajador, se ejecutará el formulario su bucle de mensajes en el hilo de trabajadores de fondo. Esto elimina el uso de un trabajador en segundo plano ya que la operación se ejecuta ahora sincrónicamente desde la vista de estímulo.

0
Pretasoc 9 sep. 2018 a las 13:55

No deberías estar creando el formulario en el hilo de fondo. Al hacerlo, se asignará el formulario a ese hilo en lugar del hilo de la interfaz de usuario, lo que significa que el formulario ahora está en un hilo diferente al de la bomba de mensajes.

Lo que puede hacer para solucionar esto es invocar la creación de instancias y la visualización del formulario en el hilo de la interfaz de usuario, entonces sus siguientes Invoke llamadas deberían funcionar.

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...

Aparte de eso, estás haciendo todo correctamente.

0
Visual Vincent 9 sep. 2018 a las 13:55