Besoin d'aide pour obtenir des informations sur un thread d'interface utilisateur et un autre thread en C #

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

Question

J'ai une application serveur qui reçoit des informations sur un réseau et les traite. Le serveur est multi-thread et gère plusieurs sockets à la fois. Des threads sont créés sans mon contrôle via les méthodes de style BeginInvoke et EndInvoke, qui sont chaînées par les fonctions de rappel correspondantes.

J'essaie de créer un formulaire, en plus de l'interface graphique principale, qui affiche un élément ListBox rempli d'éléments décrivant les sockets actuellement connectés. Donc, ce que je cherche à faire, c’est d’ajouter un élément au ListBox à l’aide de sa fonction Add (), à partir du thread sur lequel la fonction de rappel appropriée est exécutée. J'accède à mes contrôles de formulaire via la propriété Controls - I.E:

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

Naturellement, je n’appelle pas seulement la fonction, j’ai essayé de plusieurs manières de communiquer entre les threads, notamment ici et sur le Web, y compris MethodInvoker , en utilisant un délégué , en combinaison avec Invoke () , BeginInvoke () , etc. Rien ne semble fonctionner, je reçois toujours la même exception me disant que mon contrôle était accessible à partir d'un thread autre que celui sur lequel il avait été créé.

Avez-vous des idées?

Était-ce utile?

La solution

Vous devez appeler Invoke (ou BeginInvoke) sur le contrôle ListBox auquel vous accédez pour que le délégué soit appelé sur le thread qui a créé ce contrôle.

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

Autres conseils

J'ai toujours utilisé quelque chose dans ce sens:

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

J'ai également écrit un tas de méthodes d'extension d'assistance pour ... aider.

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

utilisé comme ceci:

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

Utiliser BeginInvoke ou Invoke devrait fonctionner correctement. Pourriez-vous publier un programme court mais complet qui illustre le problème? Vous devriez pouvoir en créer un qui n’a pas besoin de matériel côté serveur, mais un tas de threads qui "font semblant". recevoir des connexions entrantes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top