Oppure

Loading
02/10/11 10:13
jaco94++
Salve!

Come posso aggiungere un nuovo elemento in una listbox presente nel form da un nuovo thread in esecuzione?
Ho provato in questo modo ma non succede nulla e non si verificano neanche errori:

 public class tsl:Finder
        {
            public void ls()
            {
                TcpListener newex = null;
                Int32 port = 9100;
                IPAddress localAddr = IPAddress.Any;
                newex = new TcpListener(localAddr, port);

                newex.Start();
                Byte[] bytes = new Byte[256];
                string Mid="";
                string name = "";
                
                while (true)
                {
                    TcpClient me = newex.AcceptTcpClient();
                    if (me.Connected == true)
                    {
                        NetworkStream r_stream = me.GetStream();
                        int i;
                        while ((i = r_stream.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            temp=System.Text.Encoding.ASCII.GetString(bytes,0,i);
                        }
                    }
                    if (temp.Substring(0, 2) == "CD")
                    {
                        Mid = temp.Substring(2, 10);
                        name = temp.Substring(12);
// vengono eseguite ma non viene aggiunto nulla
            listBox1.BeginUpdate();
            listBox1.Items.Add(new { UserName = data1, MachineID = data2 });
            listBox1.DisplayMember = "UserName";
            listBox1.ValueMember = "MachineID";
            listBox1.EndUpdate();
                    }
                }

            }
        }
.
.
.

        private void Finder_Load(object sender, EventArgs e)
        {
            tsl tsl = new tsl();
            Thread T_tsl = new Thread(tsl.ls);
            T_tsl.Start();
}
aaa
02/10/11 11:06
Il Totem
E' un errore banale. Tu hai istanziato un nuovo oggetto tsl che dispone delle proprie listBox, la quali NON sono le stesse del form Finder da cui richiami Form_Load. E' quindi ovvio che non vedi nessun cambiamento.

Comunque, per evitare eccezioni dovute a chiamate cross-thread, è bene usare Form.Invoke per far richiamare dal form un certo delegato. Tuttavia non puoi riferirti al form nel tuo codice perché ti trovi in un'ulteriore classe nidificata. Infatti il sorgente che hai scritto è pieno di errori di progettazione:

1. ls non fa mai riferimento a this, né a membri di classe, giacché tsl non contiene campi e non esiste nessuna variabile non dichiarata in ls. Quindi non ha senso creare una classe derivata. Il metodo ls può funzionare benissimo nella classe base.
2. while(true) spesso è indice di un comportamento errato. Sebbene possa rientrare comodamente nell'ambito delle richieste asincrone, usalo con cautela.
3. Accettare un nuovo TcpClient ad ogni iterazione è un enorme spreco di tempo e di memoria, così come creare un nuovo stream.
4. Il while restituisce solo la fine di un messaggio. Tutto ciò che viene prima dei 256 bytes finali viene perduto.
5. Mischi il livello logico con quello di presentazione (interfaccia grafica) nello stesso codice. Non dovresti accedere alle listbox, ma lanciare un evento in occorrenza del quale il form si aggiorna.
aaa