Change a Textbox from thread and external class? C #

5

I have the following problem, I have to do a program that checks if X things are active, making queries to a database and showing them in a form.

It's something of this style more or less.

  

Note: I omit some parts of the code because I think they are not necessary for the understanding of the code or the resolution of the problem.

 _____________________________________
|_____________________________________|
|  Algo       |  Estado = activo      |
| Otra cosa   |  Estado = Pausado     |
| Y algo      |  Estado = Suspendido  |
|____ ______ ____________ ____________|                                  

The thing is that I want to control what appears on this form, the states, from a thread that is in a different class, that is, the program will do more things besides this and I'm interested in dividing it by classes and other .

The problem arises when I have to access from the thread, which in itself is a static method. This is the idea I had, I attached an example of the two classes.

public partial class Form1 : Form {
{    
     public Form1(){
          InitializeComponent();
     }

     private void controlItem_Click(object sender, EventArgs e){
            //Iniciamos el hilo padre.
            Thread principal = new Thread(Hilos.mainthread);
            principal.Start();
      }
}
class Hilos
    {

        static MySqlConnection conn;
        private Boolean error;


        public static void mainthread() {



            //Creamos la conexión con la BBDD
            string myConnectionString = "server=xx.xx.xx.xx;uid=xxxxx;" +
                                        "pwd=xxxxxx*;database=xxxxxx";

            //Intentamos la conexión

            conn = new MySql.Data.MySqlClient.MySqlConnection();
            conn.ConnectionString = myConnectionString;
            conn.Open();


            data=//Aquí iría una consulta MySQL

            if(data==xxxx){
              //Lo que quiero hacer es Form1.textbox1.text=Activo
              //Evento o algo para hacer que funcione

            }else if(data==yyyy){
              //Lo que quiero hacer es Form1.textbox1.text=Suspendido   
              //Evento o algo para hacer que funcione

            }else{
              //Lo que quiero hacer es Form1.textbox1.text=Pausado
              //Evento o algo para hacer que funcione

            }                

     }

}

Then, once the code is exposed, what I want to know is, how can I do that when one of the conditions is met, an event or something is launched (I do not know yet about events), in order to change the corresponding Textbox.

    
asked by Aritzbn 21.11.2017 в 16:02
source

2 answers

5

Although there are ways to do what you ask and the way you ask, the pattern recommended is to not do UI work in the method that makes queries to the database.

Rather, it is better to divide the responsibilities so that your method that works with the database simply returns a value that the consumer then assigns to a control in the UI.

And I assume that your desire to use a thread for the work with the database is so that the UI thread is vacated while the query is made. If this is the case, instead of working with a thread directly, today it is recommended to use Task in conjunction with async/await .

Here is an example of how to structure it:

private async void controlItem_Click(object sender, EventArgs e)
{
    textbox1.Text = await Task.Run(() => ObtenerEstado());
}

private string ObtenerEstado()
{
    // hacer consulta a la base de datos

    if (data==xxxx)
    {
        return "Activo";
    }
    else if (data==yyyy)
    {
        return "Suspendido";
    }
    else
    {
        return "Pausado";
    } 
}

It is also worth mentioning that, depending on the library you use to query the database, it may already include asynchronous methods. If this is the case, the Task would not be necessary.

    
answered by 21.11.2017 / 16:11
source
0
  

I know that this is not the best solution, but it is the one that,   temporarily, I'm going to use and I'd like to attach it because, at least   for me, it's easier to understand.

Firstly I added a class with state and name attribute, to be able to identify what the process is in case of needing it at the time of debugging.

class Estado
{
    private String estado;
    private String nombre;


    public Estado(String nombre)
    {
        this.nombre = nombre;
    }

    public void setEstado(String estado)
    {
        this.estado = estado;
    }
    public String getEstado()
    {
        return this.estado;
    }


    public void setNombre(String nombre)
    {
        this.nombre = nombre;
    }
    public String getNombre()
    {
        return this.nombre;
    }

}

In the same Thread, I create the object Estado xxxx = new Estado("Nombre del programa a monitorizar")

Then, in the Class hilos I create the state type object.

class Hilos
    {

        public static Estado nombre;

        public static void mainthread() {


            nombre = new Estado("Viva la pizza con piña"); //por ejemplo

            //Creamos la conexión con la BBDD


            data=//Aquí iría una consulta MySQL
            Thread.Sleep(3000); //Tres segundos por si acaso, mejor prevenir que curar

            if(data==xxxx){
              nombre.setEstado("Activo");

            }else if(data==yyyy){
              nombre.setEstado("Suspendido");

            }else{
              nombre.setEstado("Detenido");

            }                

     }

}

Being the public object, I can use it from the Form1 class where I simply do it.

if(nombre.getEstado().contains("Activo"){
     textbox1.text = "Activo";

 }
  

I repeat that this solution is not the most suitable, I only put it, because it is the one that has occurred to me and for reasons of time I found it   more comfortable.   I also attach it in case someone sees something that can be improved in the code, to tell me (if it is not annoying) and can improve. Greetings.

    
answered by 22.11.2017 в 07:52