Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: Event ongelma vb.net

latesoft [13.02.2008 20:38:02]

#

Koodaan VB .net 3.5:lla käyttöliittymää erääseen mikrosiruprojektiin. HW:n rajapinnoista siirtyminen olio-ohjelmointiin ei ole kovinkaan kivutonta ja jään jatkuvasti soutamaan/huopaamaan ihme rakosiin. Etenkin Eventit ja delegaatit tuottavat harmaita hiuksia. Nyt olisi seuraavanlainen ongelma, toivottavasti joku tietävä ymmärtää:

Minulla on luokka, joka taltioi erilaisia tuloksia eri hakukriteerien perusteella. Jokainen hakukriteeri on oma instanssinsa ja instanssi säilöö tuottamansa tulokset. Kun tulos muuttuu, laukaistaan kyseisessä instanssissa ChangedEvent().

Näitä hakuinstansseja hallinnoi Moduli, joka säätelee tiedon syöttämistä hakuinstansseille. Ulkopuoliset, tiedosta KIINNOSTUNEET luokat voivat hallintomodulin kautta hakea asiankuuluvan hakuinstanssin ja pultata itsensä kiinni ChangedEventiin, jotta voi reagoida muutokseen omalla tavallaan.

Nyt olen törmännyt siihen ongelmaan, että koska funktiot palauttavat kopoioita varsionaisesta instanssista, en pysty SEURAAMAAN hallintomodulin tuottamia instansseja sen ulkopuolella. Eli en pysty pulttaamaan itseäni siihen oikeaan ChangedEventiin, vaan kopioon siitä, joka ei ikinä tietenkään laukea.


Varmaankin joudun muuttamaan toimintatyyliä jotenkin, mutta haluaisin säilyttää hakuinstanssien kapseloinnin. Eli ne voitaisiin säilöä tiedosta kiinnostuneissa luokissa, mutta hallintomodulin täytyy pystyä syöttämään suoraan näille instansseille raakatietoa. Olen kokeillut tätäkin, mutta en ole onnistunut taltioimaan ByRef tietoa indeksoitavaan muotoon varsinaisen funktion ulkopuolella. Esim. MyArray(X) = VariableRef tuottaa vain kopion referenssistä, ei varsinaista pointteria alkuperäiseen (siis siihen kapseloituun hakuinstanssiin).

groovyb [13.02.2008 21:22:53]

#

pistäppä vähän koodia miten sä olet sen toteuttanut.

eli moduulista, luokastasi johon tulokset tallennetaan ja ChangedEvent():stä.

mielellään vaikka esimerkki yksittäisestä tallennustapahtumasta ja sen seuraamasta ChangedEvent():stä

ymmärsin että moduulissa käsitellään itse haku, tulos tallentuu luokkaasi ja se laukaisee tuon ChangedEvent():n

latesoft [13.02.2008 22:21:00]

#

Tässä on idea, miten sitä yritin toteuttaa, mutta kopioituminen katkaisi eventtiketjun (muuten toimi).

Class SearchCaller
    MySearch = new Tallennus(Parameters)
    MySearch = SearchModule.InsertSearch(MySearch)
    'MySearchin muuttumista halutaan jatkossa seurata reaktiivisesti
    AddHandler EventHandler, Addressof MySearch.ResultsChanged

Module SearchModule

    public function IsertSearch(ByRef Seed As Tallennus)
       'Katsotaan, onko olemassa identtinen hakutallennus, jos ei niin käytetään
       'Annettua siementä. Eventtiketju katkeaa tässä, koska en saa pointeria
       'työnnettyä takaisin kutsujalle
       If Exists = true then Tallennus = ExistingRef
       return Tallennus
    end function

    Public Sub NewData(ByVal Data)
          For Each Instance in Tallennukset
               Instance.AddResult(Data)
          next
    end sub


Class Tallennus
    Public Event ResultsChanged(ByRef Tallennus)

    Public Sub AddResult(ByRef Messages() As Communicator.SerialMessage)
        'Tässä välissä tallennusrutiini
        RaiseEvent ResultsChanged(Me)
    End Sub

groovyb [14.02.2008 00:16:04]

#

no mun järki sanoisi että se jämähtää jos on olemassa identtinen hakutallennus, koska ei ole eventtiä joka seuraisi sitä että jos sisältö ei muutukkaan.

sulla on resultschanged eventti mutta ei lainkaan eventtiä sille jos sisältö pysyykin samana.

If Exists = true then Tallennus = ExistingRef

tekeekö se tuossa todellisuudessa mitään, vai pysyykö Tallennus entisellään jos identtinen hakutallennus on jo olemassa.

neau33 [14.02.2008 00:21:56]

#

Moikka latesoft!

pari asiaa, jotka pistivä silmään näin äkkiseltään...

'...
'ehkä kannattaisi eliminoida mahdollisuus, että jäisi kantamaan...
MySearch = Nothing '*
MySearch = new Tallennus(Parameters)


'olisiko funktion tarkoitus palauttaa jotain...?
Public Function InsertSearch(ByRef Seed As Tallennus) 'As Tyyppi?
'(voisiko tyyppi olla vaikkapa MySearch)

'Exists mitä?  ...ja mitä sitten jos Not Exists?
If Exists = true then Tallennus = ExistingRef
'[k]jos tyyppi ei ole 'MySearch' tuntuisi äkkipäätä loogiselta,
'että jos identtinen hakutallennus löytyy niin funktio palauttaisi
'vaikka stringin "don't do anything" ja jos vastaavuutta ei löydy
'niin Return olisi vaikka "do something"...[/k]

RaiseEvent ResultsChanged(Me)
'ettei pääsisi syntymään mahdollisia päällekkäisyyksiä...
RemoveHandler EventHandler, Addressof MySearch.ResultsChanged '*

latesoft [14.02.2008 08:24:52]

#

Kiitos vastauksista. InsertSearchin tarkoitus oli palauttaa AINA sellainen Tallennus-instanssi, jonka eventtiä kannattaa seurata. TAvallaan kutsujaluokan antama MySearch käännettäisiin modulin osoitteistoon (mikä ei tuntunut onnistuvan). Onko niin, että jokaista eventiä varten voi tehdä vain yhden handlerin? Sehän nimittäin kaataa tämän idean jo heti.

Tänään joudun tekemään asialle jotain, mutta joudun keksimään menetelmän, jonka avulla SearchModule pystyy tekemään seuraavaa:

1. Jakamaan tietoa sitä etsiville instansseille. Voinhan sen tehdä niinkin, että hakija kutsuu funktiota, joka palauttaa hakutulokset.

2. Hyvin mielellään eventpohjainen päivitys. Eli tietoa etsivän ei tarvitse pollata jatkuvasti, onko uutta dataa, vaan kun uutta dataa ilmestyy, etsivä luokka saa ilmoituksen. Tämä on ollut pääasiallinen ongelma.

neau33 [14.02.2008 12:14:40]

#

latesoft kirjoitti:

...Jokainen hakukriteeri on oma instanssinsa ja instanssi säilöö tuottamansa tulokset. Kun tulos muuttuu, laukaistaan kyseisessä instanssissa ChangedEvent().

latesoft kirjoitti:

Onko niin, että jokaista eventiä varten voi tehdä vain yhden handlerin? Sehän nimittäin kaataa tämän idean jo heti.

Eikä mitään kaada, idea on sinällään loistava...
Jos kerran eventin laukaisua yritetään vain ja ainoastaan silloin, kun tulos muuttuu niin mielestäni on aika loogista, että kun event on laukaistu handler pyyhkäistään 'nevadaan'. Kun tulos muuttuu ja käsittelijää tarvitaan, luodaan ko. instanssin tarpeita varten aina uusi mikä estää myös kopioiden syntymisen.
Eli handler luodaan vain jos InsertSearch-funktio palauttaa OK:ta (doesn't Exists). Identtisen hakutuloksen kohdatessaan funktion palautteeksi voi huoletta säätää Ei-OK:ta koska kaikki mahdollisten jatkotoimien tarvitsema tieto on jo säilössä...

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta