Red de conocimiento informático - Computadora portátil - C# ¿Cómo configurar las propiedades visibles y habilitadas de un botón usando la API?

C# ¿Cómo configurar las propiedades visibles y habilitadas de un botón usando la API?

Después de .net 2.0, el mecanismo de seguridad se ha reforzado y no se permite el acceso directo entre subprocesos a las propiedades de los controles en winform. Entonces, cómo resolver este problema, aquí hay algunas opciones. CheckForIllegalCrossThreadCalls = false;

Hilo = new Thread(ThreadFuntion);

hilo.IsBackground = verdadero

hilo.Start();

hilo.IsBackground = verdadero;

hilo.Inicio();

hilo.IsBackground = verdaderoInicio()

}

Después de agregar este código, encontramos que el programa comenzó a ejecutarse. Este código ilustra que en esta clase, no verificamos si la llamada entre subprocesos es legal (si el tiempo de ejecución no verifica la llamada entre subprocesos y no se genera ninguna excepción, el sistema no la verificará de forma predeterminada). Sin embargo, este enfoque no es aconsejable. Si miramos la definición de la propiedad CheckForIllegalCrossThreadCalls, veremos que es una propiedad estática, lo que significa que no importa dónde cambiemos el valor en el proyecto, funcionará globalmente. Por lo general, buscamos excepciones como esta para el acceso entre subprocesos. Si alguien más en el proyecto modifica esta propiedad, entonces nuestra solución falla y tenemos que recurrir a una solución diferente.

Echemos un vistazo a la segunda solución, que consiste en utilizar delegación y llamadas para controlar la información de control de otro hilo. Hay mucha gente escribiendo en línea sobre este tipo de control, pero también he leído muchos artículos sobre este tema donde se afirma que parece no haber ningún problema, pero en realidad no resuelve el problema.

Primero, veamos la forma imperfecta de hacerlo en la web:

clase pública parcial Form1: Formulario

{

delegado privado void FlushClient(); //proxy

form1 público()

{

InitializeComponent();

}

vacío privado Form1_Load(remitente del objeto, EventArgs e)

{

Hilo hilo = nuevo hilo(CrossThreadFlush);

hilo.IsBackground=true;

thread.Start();

}

private void CrossThreadFlush()

{

// Vincular el proxy Ir a el método

FlushClient fc = new FlushClient(ThreadFuntion);

this.BeginInvoke(fc)BeginInvoke(fc); //invocar el proxy

}

private void ThreadFuntion()

{

while (true)

{

this.textBox1. = DateTime.now.ToString();

Thread.Sleep(1000);

}

}

}

Usando este enfoque, podemos ver que la excepción para el acceso entre subprocesos ha desaparecido. Pero apareció un nuevo problema, la interfaz no respondía. ¿Por qué ocurre este problema? Simplemente dejamos que el hilo recién abierto se actualice en un bucle infinito. En teoría, no debería tener ningún impacto en el hilo principal. De hecho, este método es equivalente a "inyectar" un nuevo hilo en el hilo de control principal y obtiene el control del hilo principal. Mientras el hilo no regrese, el hilo principal nunca podrá responder. Incluso si el hilo recién abierto no utiliza un bucle infinito, puede regresar. El uso de subprocesos múltiples de esta manera anula el propósito del subproceso múltiple.

Ahora veamos la solución recomendada:

clase pública parcial Form1: Formulario

{

delegado privado void FlushClient (); //proxy

public Form1()

{

InitializeComponent()

}

private void; Form1_Load(remitente del objeto, EventArgs e)

{

Hilo hilo = new Thread(CrossThreadFlush);

hilo.IsBackground = true;

p>

thread.Start();

}

private void CrossThreadFlush()

{

while ( true)

{

//Pon el modo de suspensión y el bucle infinito fuera de wait async

Thread.Sleep(1000);

ThreadFunction; () ;

}

}

}

función de rosca privada vacía()

{

if (this.textBox1.InvokeRequired)//Esperar asíncrono

{

FlushClient fc = new FlushClient(ThreadFunction);

this. Invoke(fc ); // Llama al método de actualización a través del proxy

}

else

{

this.textBox1.Text = DateTime .Ahora. ToString();

}

}

Al ejecutar el código anterior, podemos ver que el problema se ha resuelto, al esperar asíncrono, No siempre tendrá el control de subprocesos maestro, esto nos permitirá completar el control de subprocesos múltiples del control de subprocesos múltiples de winform sin excepciones de llamadas entre subprocesos.

Recientemente encontré una mejor solución a la pregunta formulada por Deep Old Woods, que es utilizar una llamada asincrónica al delegado, como puedes ver:

clase parcial pública Form1: Formulario

{

delegado privado void FlushClient(); //proxy

formulario público1()

{

InitializeComponent();

}

private void Form1_Load(remitente del objeto, EventArgs e)

{

Hilo = nuevo Hilo (CrossThreadFlush);

hilo.IsBackground = verdadero;

hilo.Start()

}

private void CrossThreadFlush()

{

FlushClient=new FlushClient(ThreadFunction);

FlushClient.BeginInvoke(null)BeginInvoke(null, null);

}

private void ThreadFunction()

{

while (verdadero)

{

this.textBox1.Text = DateTime.Now.ToString( );

Thread.Sleep(1000

}

}

}

}

Este enfoque también se puede simplificar directamente (porque el delegado asincrónico simplemente abre un hilo asincrónico):

clase parcial pública Form1: Formulario

{

delegado privado void FlushClient(); //proxy

formulario público1()

{

InitializeComponent();

}

private void Form1_Load(remitente del objeto, EventArgs e)

{

Hilo = nuevo Thread( CrossThreadFlush);

FlushClient=new FlushClient(ThreadFunction);

FlushClient.BeginInvoke(null, null);

}

Private void ThreadFunction()

{

while (true)

{

this.textBox1.Text = DateTime.Now. ToString( );

Thread.Sleep(1000

}

}

> }

}