Hai bisogno di aiuto per ottenere informazioni attraverso un thread dell'interfaccia utente e un altro thread in C #

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

Domanda

Ho un'applicazione server che riceve informazioni su una rete e le elabora. Il server è multi-thread e gestisce più socket contemporaneamente e i thread vengono creati senza il mio controllo attraverso i metodi di stile BeginInvoke ed EndInvoke, che sono concatenati dalle corrispondenti funzioni di callback.

Sto cercando di creare un modulo, oltre alla GUI principale, che visualizza un elemento ListBox popolato da elementi che descrivono i socket attualmente connessi. Quindi, quello che sto sostanzialmente cercando di fare è aggiungere un oggetto a ListBox usando la sua funzione Aggiungi (), dal thread su cui è in esecuzione la funzione di callback appropriata. Accedo ai controlli dei miei moduli tramite la proprietà Controls - I.E:

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

Naturalmente non solo chiamo la funzione, ho provato diversi modi che ho trovato qui e sul web per comunicare tra i thread, tra cui MethodInvoker , usando un delegato , in combinazione con Invoke () , BeginInvoke () ecc. Nulla sembra funzionare, ricevo sempre la stessa eccezione che mi dice che al mio controllo è stato effettuato l'accesso da un thread diverso da quello su cui è stato creato.

Qualche idea?

È stato utile?

Soluzione

Devi chiamare Invoke (o BeginInvoke) sul controllo ListBox a cui stai accedendo per poter chiamare il delegato sul thread che ha creato quel controllo.

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

Altri suggerimenti

Ho sempre usato qualcosa del genere:

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

Ho anche scritto un sacco di metodi di estensione dell'helper per ... aiutare.

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

utilizzato in questo modo:

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

L'uso di BeginInvoke o Invoke dovrebbe funzionare correttamente. Potresti pubblicare un programma breve ma completo che dimostra il problema? Dovresti essere in grado di elaborarne uno che in realtà non ha bisogno di roba sul lato server - basta avere un sacco di thread che "fingono" per ricevere connessioni in entrata.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top