Toon posts:

[.NET] Data uitwissellen tussen threads

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste devvers,

Normaliter doe ik niet zoveel met threading, hoogstens een bgworker waar er flink wat werk verzet moet worden en de UI moet blijven functioneren.

Nu zit ik met het probleem dat ik een soort 'listner' heb die voordurend in een while loop zit. Deze 'listner' is gewoon een method van een classe. Nu maak ik een nieuwe threat met New Thread(AddressOf Me.oKlasse.Start) [vb]... So far so good.

Het eerste wat in je op komt als je altijd singlethreaded werkt is natuurlijk gewoon een event maken in dat object met die listner (die we even klasse B noemen), deze raisen in je while loop en deze vanuit je hoofdobject (klasse A) afhandellen. Je geeft de data mee die je 'afgeluisterd' hebt the loop goes on...

Opzich werkt dat. Echter is het nu opeens zo dat de event handler die je in klasse A gedefineerd hebt opeens in object B uitgevoerd wordt...? Terwijl ik wel gewoon in mijn private membervelden van object A kom? Nu zou me dat ook niet opvallen allemaal eigenlijk -> tot je je private memberveld aan een UI control hangt, die komt dan opeens met een exception als "Het is niet toegestaan een bewerking uit te voeren via verschillende threads: er werd vanaf een andere thread toegang gekregen tot het besturingselement lbxLog dan de thread waarop het element is gemaakt."

Nu hoef ik uberhaubt niet met controls te werken want in deze app teken ik alles met managed directx, en ja ik weet dat je met CheckForIllegalCrossThreadCalls hier omheen kunt werken.

Maar hoe moet ik dit eigenlijk oplossen? Dan bedoel ik ook niet zo zeer het locken van data in een threat maar meer het doorgeven van 'berichten' tussen mijn threads dat er nieuwe data is...? Eigenlijk leggen de meeste .NET threading artiekellen die ik vind vooral de nadruk op processen die hun data doorgeven als ze klaar zijn.... Die van mij moet dat dus doen als er iets 'gebeurt'.

Edit: voor iedereen me naar de search verwijst (zie opeens veel over dit topic op GoT) ik wil hier dus geen BackgroundWorker gebruiken en ik heb niks met de UI te maken!

[ Voor 5% gewijzigd door Verwijderd op 11-02-2008 14:05 ]


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Doe eens een GOT search met keyword 'ISynchronizeInvoke'. Voorbeelden genoeg en bijbehorende discussies betreffende de implementatie (in event raise methode) of bij de afvang van het event.

Het probleem welke je hier hebt is niet anders dan het probleem wanneer je user controls vanuit een andere thread wilt benaderen. De System.Threading namespace heeft overigens wel enkele oplossingen om variabelen (objecten) tussen threads te delen. Denk daarbij aan Interlocked class of volatile keyword in C#.

De 'scope' waarin de variabele (object) gedeelt moet worden, bepaald eigenlijk ook welke methode het beste is. Ik beperk meestal deze scope als parent <--> child references (zoals HttpContent references heeft naar HttpRequest, HttpResponse en Page) en globale singleton implementaties (HttpContext.Current).

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 22-09 19:06

Gerco

Professional Newbie

Gebruik dan iets als een event queue. Ik weet niet zeker hoe dat in .NET werkt, maar er is vast wel een BlockingQueue of iets wat daarop lijkt. Vanuit je ene thread stop je dan objecten in die queue en met je andere thread haal je ze er weer uit. Als je BlockingQueue ook nog eens zelf synchronized (wel zo handig), hoef je niet eens over threading na te denken.

Er staat me ook iets bij dat je een delegate aan die thread kan geven als event handler en dan delegate.invoke() kan gebruiken (na eerst via invokeRequired() even te checken of dat wel nodig is).

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@Niemand
Ivm met ISynchronizeInvoke:
http://vbcity.com/forums/faq.asp?fid=15&cat=Threading

Leuk idd....
Maar met die link geef ik antwoord op mn eigen vraag denk ik.... Delegates moeten dus mijn events vervangen in dit geval that's it. Wist niet dat je boos werd ;)

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Ik ben zeker niet boos ;-) Heb nog genoeg alcohol van het carnaval in m'n bloed, dus happy, happy, happy..

Daarbij moeten inderdaad de delegates via de ISynchronizeInvoke de events afvangen. Whoami heeft een tijd geleden ook een post gedaan waarbij de synchonisatie in de aanroepende class (OnXX methode) werd geregeld. Vandaar mijn opmerking betreffende de search omdat beide methodieken hun voor- en nadelen hebben.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:06
Nog eens ivm die ISynchronizeInvoke; dit werkt enkel voor WinForms.
Als je gebruik gaat maken van een WPF applicatie bv, dan zal dit niet meer goed gaan, want WPF controls implementeren ISynchronizeInvoke niet.

De manier op dit op te lossen, in .NET 3.5, is door gebruik te maken van de AsyncOperationManager en de AsynOperation classes.
(Ik heb trouwens gezien dat ze in .NET 3.5 de BackGroundWorker implementatie ook veranderd hebben, zodanig dat deze ook gebruik maakt van de AsyncOperationManager. Deze gaat er nl. voor zorgen dat de juiste AsyncOperation gecreeërd wordt (afhankelijk van de 'context'), zodanig dat je op een juiste manier je events kunt invoken.

/kickje, maar ik vond het wel nuttig. :P

[ Voor 3% gewijzigd door whoami op 20-05-2008 17:13 ]

https://fgheysels.github.io/

Pagina: 1