c# tömb vagy lista küldése szálak között

 ( LLZoli | 2011. január 24., hétfő - 21:49 )

Holnapra meg kellene csinálnom a c# gui részéből a beadandómat. Egy kis "feladatkezelőn" dolgozok, lényeg az, hogy lekéri a folyamatlistát egy timer segítségével, ami egy backgroundworker-t indít 2 másodpercenként. Az egész majd egy ListView-ben jelenne meg, ami több oszlopot tartalmaz. Mivel ez egy másik szálon fut, így nem férek hozzá az eredeti szálban található ListView-hez. Google segítségével megtudtam, hogy delegátum segítségével szépen lehet szálak között üzenni. Két problémába ütköztem.

  1. Ha a tömb minden elemét külön külön küldöm el egy ListViewItem subitemjei segítségével, akkor nagyon belassul, mindig ugyanazt küldözgeti. Vagy 3 különbözőt, de nem azt amit belepakoltam. Pl mindig a második elemmel kezdi.

  2. Ha tömböt, ha listát szeretnék átadni neki mindig dob egy kivételt, miszerint túl sok a paraméter neki.

Kód idevágó része:

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Diagnostics.Process[] p = System.Diagnostics.Process.GetProcesses();
            SetTextCallback d = new SetTextCallback(SetText);
                                  
            this.Invoke(d, p);
        }

        public delegate void SetTextCallback(System.Diagnostics.Process[] items);

        private void SetText(System.Diagnostics.Process[] items)
        {
            ListViewItem list = new ListViewItem();
            
            foreach (System.Diagnostics.Process p in items)
            {
                list.SubItems[0].Text = p.Id.ToString();
                listView1.Items.Add(list);//itt már csak próbának, hogymegjelenik-e
            }
        }

Egyébként valószínűleg én vagyok a hülye, tudom. Gondolom 2-5 sorból meg lehetne oldani.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Ha az Invoke(object obj, object[] parameters) formáról van szó, akkor a gond az, hogy a Process[]-t castolja object[]-re, tehát helyesen: Invoke(d, new object[]{p})

Példaprogramból másoltam ki. A leírás szerint ez végzi a szálak közti küldést lényegében. Kipróbáltam, ugyanaz a hibaüzenet:

A következő elem nem adható hozzá vagy szúrható be egynél több helyre: „1372”.
Először el kell távolítania jelenlegi helyéről, vagy pedig klónoznia kell.
Paraméter neve: item

A legjobb az, hogy nincs ilyen változóm, de még az itt használt objektumoknak sincs item adattagja. Hát ha éjfélig nem jövök rá, akkor marad az, hogy szövegenként küldöm át - jaj de csúnya lesz...

Milyen osztályban definiáltad a backgroundWorker1_DoWork() metódust? Akkor már legalább lehetne tudni, hogy a this.Invoke() valójában mit hív...

Szerk.: Közben rájöttem, hol lesz a gondod: ha a listView1 elemeit akarod módosítani, akkor a hívás helyesen:
listView1.Invoke(d, new object[]{p});
Viszont ez nem elég! a listView1 hatókörében elérhetőnek kell lennie d-nek, tehát azt ne a (vélhetően) form egy privát függvényében tessék definiálni.

egy egyedi kontrol saját osztályában. a timer is az osztályban van, ami hívja időközönként a workert.

(Bevallom hősiesen, baromi ritkán használok Windows.Formsot, WPF-et még inkább, többnyire parancssoros kódokat írok linuxon admin feladatokhoz, illetve automatizáló "scripteket" InDesignhoz és Photoshophoz, néha ASP.NET cuccokat.)

A SetText-ben csak egy ListViewItem példányt hozol létre, és azt akarod többször hozzáadni a listView1 Items kollekciójához. Attól, hogy egy propertyjét megváltoztatod, az még ugyanaz a példány.

tehát akkor a ciklusban hozzak létre az új változót mindig?

igen

ezt miert kell backgroundworkerrel csinalni? olyan lassu a getprocesses, hogy megfogja a guit?

amugy egy lista frissitese nemkis melo: eloszor is ki kell torolni azokat az elemeket amik mar nemkell bele (leallitottak egy progit), majd a meglevok adatait frissiteni, es vegul az ujakat hozzaadni.

--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

esetleg mindig újra hozzáadni őket? nem a getprocess hanem a timer, amig nem tickel addig áll a gui.

??? miert all a gui amig nem tickel? :o

a hozzaadassal az a baj, hogyha akarsz elemet kijeloltetni, akkor az user fraszt fog kapni, mivel a kijelolese elveszik a clear() hatasara...

--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

viszont, ha lementem előtte a pidet, akkor az új listában ki tudom választani a azt a sort.

Vagy praktikusan kidobni mindent a listából, és újra hozzáadni...