Error in System.Windows.Forms.Control.inCrossThreadSafeCall

1

Good morning, I have an application that in a given moment throws a Thread, inside that Thread it is called a user control where an image is put in a button inside the user control.

The user control has a list of Tuples composed of a TextBox and a Button, in order to know which Button is associated with each TextBox.

The problem I have when I try to search within that list of tuples to which button you have to put the image.

I put the code used:

The part where the Thread is created to run in the background:

 Thread preparaPDF = new Thread(() => lanzaComprobacionPDFIndividual(idActual));
                preparaPDF.IsBackground = true;
                preparaPDF.Start();

Inside the PDDFindividualTraveler launches the user control visorPDF is called:

visorPDF.anadeFichero(listaIDs[idActual], ficG, true);

and the function where I get the error, is in anadeFichero

 public void anadeFichero(string id, string ruta, bool bueno)
    {
        try
        {
            Button b = (Button)listaRelacionada.Find(x => (x.Item1 as TextBox).Text == id).Item2;
            if (b != null)
            {
                b.Tag = ruta;
                habilitaBoton hab = new habilitaBoton(enableBoton);

                b.Invoke(hab, b, bueno);
            }
        }
        catch (Exception ex)
        { }
    }

In fact, I've put a try catch in case it throws an exception but does not throw anything, it stops there.

This error is very strange to me, since as it is seen in theRelated list, if there are values.

Then I put a screenshot of how it looks in debug.

Thanks for the help.

    
asked by U. Busto 31.01.2018 в 11:10
source

1 answer

0

Good, I have managed to solve this issue in the following way: Instead of being with a process in background, thread or task looking when the pdf is generated, I do it by means of a timer that checks every 500 milliseconds if the file was generated, once the file was found, to modify the graphic interface of the control of user I have adapted a class that I found in English Stackoverflow, that I put below:

  public static class ThreadHelperClass
{
    delegate void SetTextCallback(UserControl f, Control ctrl, string ruta, bool bueno, Bitmap imagen);
    /// <summary>
    /// Set text property of various controls
    /// </summary>
    /// <param name="form">The calling form</param>
    /// <param name="ctrl"></param>
    /// <param name="text"></param>
    public static void activarBoton(UserControl form, Control ctrl, string ruta, bool bueno, Bitmap imagen)
    {
        // InvokeRequired required compares the thread ID of the 
        // calling thread to the thread ID of the creating thread. 
        // If these threads are different, it returns true. 
        if (ctrl.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(activarBoton);
            form.Invoke(d, new object[] { form, ctrl, ruta, bueno, imagen });
        }
        else
        {
            ctrl.Enabled = true;
            ctrl.Tag = ruta;
            ctrl.BackgroundImage = imagen;

        }
    }

Then, instead of looking for the button in the list of controls where it is and creating a copy of it, I use it directly as follows:

ThreadHelperClass.activarBoton(this, listaControles[i] as Button, rutaEnCurso, resultadoEnCurso, bit);

being routeEnCurso the location of the pdf, resultEnCourse if the result of the test has been good or not and bit the bitmap that is passed to the button.

Thank you very much everyone for the help and the ideas.

    
answered by 02.02.2018 / 11:43
source