¿Necesita ayuda para obtener información a través de un subproceso de interfaz de usuario y otro subproceso en C #

StackOverflow https://stackoverflow.com/questions/229254

Pregunta

Tengo una aplicación de servidor que recibe información a través de una red y la procesa. El servidor tiene varios subprocesos y maneja múltiples sockets a la vez, y los subprocesos se crean sin mi control a través de los métodos de estilo BeginInvoke y EndInvoke, que están encadenados por las funciones de devolución de llamada correspondientes.

Estoy intentando crear un formulario, además de la GUI principal, que muestra un elemento de ListBox lleno de elementos que describen los sockets conectados actualmente. Entonces, lo que básicamente estoy tratando de hacer es agregar un elemento al ListBox usando su función Add (), desde el hilo en el que se está ejecutando la función de devolución de llamada apropiada. Estoy accediendo a mis controles de formularios a través de la propiedad Controles - I.E:

(ListBox)c.Controls["listBox1"].Items.Add();

Naturalmente, no solo llamo a la función, he intentado varias formas que he encontrado aquí y en la web para comunicarme entre los subprocesos, incluido MethodInvoker , usando un delegado de , en combinación con Invoke () , BeginInvoke () etc. Nada parece funcionar, siempre recibo la misma excepción que me dice que se accedió a mi control desde un subproceso distinto al que se creó en.

¿Algún pensamiento?

¿Fue útil?

Solución

Tienes que llamar a Invoke (o BeginInvoke) en el control ListBox al que estás accediendo para que se llame al delegado en el hilo que creó ese control.

ListBox listBox = c.Controls["listBox1"] as ListBox;
if(listBox != null)
{
   listBox.Invoke(...);
}

Otros consejos

Siempre he usado algo en este sentido:

        c = <your control>
        if (c.InvokeRequired)
        {
            c.BeginInvoke((MethodInvoker)delegate
            {
                //do something with c
            });
        }
        else
        {
            //do something with c
        }

También escribí un montón de métodos de extensión de ayuda para ... ayuda.

using System;
using System.ComponentModel;
public static class CrossThreadHelper
{
    public static bool CrossThread<T,R>(this ISynchronizeInvoke value, Action<T, R> action, T sender, R e)
    {
        if (value.InvokeRequired)
        {
            value.BeginInvoke(action, new object[] { sender, e });
        }

        return value.InvokeRequired;
    }
}

utilizado de esta manera:

     private void OnServerMessageReceived(object sender, ClientStateArgs e)
    {
        if (this.CrossThread((se, ev) => OnServerMessageReceived(se, ev), sender, e)) return;
        this.statusTextBox.Text += string.Format("Message Received From: {0}\r\n", e.ClientState);
    }

El uso de BeginInvoke o Invoke debería funcionar bien. ¿Podrías publicar un programa corto pero completo que demuestre el problema? Debería poder crear uno que no necesite realmente ningún elemento del lado del servidor; solo tiene un montón de subprocesos que " fingir " para recibir conexiones entrantes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top