Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Forum översikt / inlägg

Posta nytt inlägg


Flytta över exekvering till annan tråd.

Postades av 2004-01-18 11:35:46 - Patrik Löwendahl, i forum c# (c-sharp), Tråden har 15 Kommentarer och lästs av 1995 personer

Försöker implementera samma funktionalitet som Control.Invoke(MethodInvoker) använder sig av.

Jag vill alltså ifrån en arbetstråd (bakgrundstråd) skicka en delegat till huvudtråden och låta instruera huvudtråden att exekvera delegaten. I praktiken är det en "Execution marshalling" jag är ute efter.

Jag har spårat funktionalitet i Control.Invoke till en metod som heter MarshalInvoke. Den verkar var skriven i unmanaged c++ på något sätt, har fastnat där.

Frågan är alltså, hur ska jag lyckas skicka ett delegatobjekt från en tråd till en annan och låta den senare exekvera delegaten?


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-18 12:48:50 - Oskar Johansson

Det finns ju nå'n "threaddata" som du skulle kunna använda tror jag... Se till så att den alltid innehåller en egenskriven klass med lite events i... På så sätt kan huvudtråden lägga till en eventhandler för ett event i den klassen med nå't kommandon (AddHandler i vb.net iaf.) och arbetstråden kan låta eventet i klassen "gå av" när delegaten skall över... Jag har inte en aning om ifall det här är trådsäkert, men du lär iaf. behöva gör en lock på klassen först...


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-18 14:04:38 - Roger Alsing

nu gissar jag villt här men.

är det inte så att control.invoke inte flyttaröver exekveringen utan snarare bakom kulisserna skickar ett meddelande till kontrollens wndproc
som sedan processas av huvudtråden , den hittar meddelandet och med wparam/lparam så får den en pekare till någon strukt som innehåller delegaten som ska anropas.

om det är så , så går det bara göra detta om det finns något som processar fönster meddelanden..

men som sagt det är en gissning..


för att fortsätta att inte svara på din fråga och bara gissa lite mer.
kan du inte ha en arraylist som är syncad mellan trådarna och i din bakgrundstråd fylla listan med delegate som ska anropas
och sedan låta huvudtråden polla listan och anropa dessa delegater?


//Roger

ps.
jaja det är nog bäst att låta sjögren ta denna ;-)


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-18 14:17:01 - Mattias Sjögren

>jaja det är nog bäst att låta sjögren ta denna ;-)

Har inte så mycket att tillägga, det du skrev låter korrekt. Control.Invoke är väl implementerad med API:et PostThreadMessage om jag kommer ihåg rätt.


MS


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-18 20:03:14 - Patrik Löwendahl

<b>Onkelborg:</b> om jag signalerar ett event från en arbetstråd så kommer även eventanteraren att exekveras på den tråden, inte på huvudtråden. Tyvärr verkar många ha missuppfattat hur trådning och delegater fungerar tillsammans.

Jag har fått flera förslag om just det här med events och det verkar som den allmänna uppfattningen är att när en eventdelegat exekveras så är det huvudtråden som hanterar den, det stämmer inte.

Det är alltid tråden som invokerar delegaten (vare sig det är en "vanlig delegat" eller en eventdelegat), som sedan exekverar metoden den pekar på (eller det är inte riktigt sant heller när det gäller asynkron exekvering av delegater, men då sker det på ännu en ny arbetstråd och inte på huvudtråden).

<b>Roggan:</b> Det är absolut en snygg workaround, men fortfarande bara en workaround ;) Man kan tänka sig att bygga en egen messagepump och använda System.Collections.Queue för att köa meddelanden till huvudtråden, men hur pollar man enklast en sådan kö utan att huvudtråden låses upp? Man vill ju att den skall fortsätta att exekvera övrig kod.

<b>Mattias:</b> Har du någon länk till mer information om det api'et? Hade det inte varit för att System.Threading.Thread var sealed så skulle man ju kunna utöka den vidare med liknande funktionalitet.


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-18 20:13:54 - Oskar Johansson

Hm... Events skall väl gå över flera trådar om jag inte tar helt fel?


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-18 20:51:26 - Patrik Löwendahl

Alltså, om du har två trådar, a och b, och du i tråd b exekverar ett event, då kommer även eventhanteraren (den som du i vb markerat med handles och i C# mer intuitivt lagt till i invokeringslistan med +=) att exekveras av tråd b.

Detta är ett problem med windowsformulär bland annat, där man måste skicka alla delegater som skall uppdatera ngn av dina kontroller, via Control.Invoke för att anropet skall göras på huvudtråden.

Så gör du något i en bakgrundstråd och tex vill uppdatera en progressbar, då måste du använda dig av myForm.Invoke(new MethodInvoker(updateProgress)); för att det skall lyckas, du kan <b>inte</b> bara signalera ett event som uppdaterar progressbaren eftersom det då inte skulle ta bort prylen med att vi inte är på huvudtråden.

Och Ja, om du provar så kommer progressbaren att i 7 fall av 10 uppdateras utan problem, men nej det betyder inte att det är huvudtråden som gör det. Enklaste sättet att kolla det här är att sätta upp ett scenario med ett par trådar, signalera ett event och i Thread fönstret i VS.NET kolla vilken tråd som exekverar koden.

Det vill säga, events går <b>inte</b> över flera trådar. Vet inte var folk får det här magiska tänket runt events ifrån, de är helt enkelt metodpekare vi skapat och standariserat med hjälp av event nyckelordet och genom att följa designmönstret för eventhanterarna (event delegaten)


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-18 22:47:11 - Fredrik Normén

Nu har jag inte testat detta och det är en vild gissning, du kanske skulle kunna lösa det hela med en singelton där du placerar din huvudtråd?

/Fredrik Normén NSQUARED2



Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-19 09:26:22 - Patrik Löwendahl

det skulle lösa det hela hur?

menar du att jag skulle dra igång en singleton och lägga huvudtråden på en AutoresetEvent och vänta på signalering??? Eller hur då?


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-19 11:10:39 - Fredrik Normén

hmm, tror inte min teori funger nu när jag tänker efter.

Kan detta ev lösa ditt probelem:
http://docs.msdnaa.net/ark_new3.0/cd3/content/Type_Sample%20Applications.htm#title5_13 ???

/Fredrik Normén NSQUARED2


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-19 12:37:41 - Patrik Löwendahl

Jo resetevents kan lösa det, men då måste jag skapa en egen message loop och via waithandles eller resetevents signalerar meddelande loopen att ett nytt meddelande kommit. Funkar fint i consol applikationer men inte i windows formulär eller windows services och jag är lite ute efter en generell lösning som sagt.

Men verkar som jag får ge upp det så länge och bygga specifika lösningar beroende på klient *suck*


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-19 22:17:42 - Mattias Sjögren

>Mattias: Har du någon länk till mer information om det api'et?

Nej tyvärr, inget förutom det du nog själv kan hitta i MSDN.


Du kan ju inte tvinga en existerande tråd att helt plötsligt avbryta det den håller på med och köra en eventhanterare, så jag tror du är tvungen att välja nån slags meddelandeloop eller pollningsliknande lösning, hur du än vrider på det.


MS


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-20 08:39:23 - Roger Alsing

får man fråga vad det är du ska göra?
det kanske går att vrida och vända på problemet på någe sätt :)

vad är det för jobb som ska köras i huvudtråden och vad är det för någe som ska anropas via delegater i arbetstråden?

tänkte om det går att göra något special special , så att det jobb som nu körs i huvudtråden flyttas in i ytterligare en tråd , och låta huvudtråden bara polla vad som skett i de båda arbetstrådarna..

//Roger


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-20 12:46:49 - Patrik Löwendahl

Jag skriver ett par generella funktionsbibliotek, i flera klasser i de här bilioteken så vill jag att klienter skall få prenumerera på händelser och i många fall är de här klasserna multi-trådade.

Ibland kan dessa klienter vara windowsformulär, ibland är de inte det.

När de är windows formulär så vill jag att eventet skall triggras på huvudtråden, för att eventhanteraren skall kunna uppdatera kontroller och dylikt via den vanliga messagepumpen.

Som det är nu måste jag i min eventhangerare, <b>om</b> klienten är ett windowsforumulär, skapa en methodinvoker och använda myForm.Invoke för att uppdatera kontroller. Jag vill undvika det eftersom det då kräver mer från den som använder mina klasser.

Därför skulle jag vilja låta eventet triggras på huvudtråden, då spelar det ingen roll vad det är för klient eller vad klienten exekverar för kod vidare i händelsehanteraren.


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-01-20 12:48:36 - Patrik Löwendahl

Mattias:

I hear you, och självklart är det som du säger. En tråd är ju upptagen med något hela tiden om den lever, för en huvudtråd i ett formulår så innebär det ju att serva en messagepump och i en konsol applikation att exekvera main tills den avslutas.


Svara

Sv: Flytta över exekvering till annan tråd.

Postades av 2004-04-30 16:04:39 - Patrik Löwendahl

Svarar mig själv.

Efter att ha blivit triggad av Andreas Håkanson så har vi lyckats leta fram ett svar.

Svaret är ett litet trick där vi använder data från event-delegaterna tillsammans med "runtime type casting"

Alla event har en sk "MulticastDelegate" som bas, en MulticastDelegat innehåller 1+ sk "SingelCastDelegate" som pekar på en enskild metod på ett enskilt objekt. Dessa delegater skapas när vi lägger till event-hanterare för vårt event. Bas-delegaten har en egenskap som heter <b>InvocationList</b> som är en lista på alla "SingelCastDelegater" vilka har bett om att bli signalerade när någon exekverar ett event.

Varje delegat innehåller dessutom egenskapen <b>Target</b>, den pekar på objektet i vilken metoden som vi skall signalera är definerad.

Tricket är att iterera igenom alla målmetoder som finns i <b>InvocationList</b> och helt enkelt avgöra om metoden är definerad i ett objekt som kräver synkroniserad-exekvering. För kontroller (forumulär, knappar osv) så är detta sant.

För att stödja synkroniserad-exekvering på dessa kontroller så har MS skapat interfacet <b>ISynchronizeInvoke</b> vilket definerar stöd för BeginInvoke och Invoke för att flytta exekveringen av delegater till huvudtråden som handhar meddelandepumpen för applikationen.

Vi nyttjar sedan <b>As</b> operatorn för att avgöra om objektet som delegaten pekar på implementerar nämnda interface, är så fallet exekverar vi eventet genom "Target" objektet istället för att använda den vanliga delegate syntaxen.

Nedan är ett exempel på hur det kan se ut:

		protected void SyncInvoke(Delegate del, object sender, EventArgs e)
		{			
			// Make sure that the delegate is instanciated
			if (del != null) {
				
				// Create an object array which will hold
				// the arguments sent to the event handler 
				// function
				object[] arguments;			
				arguments = new object[2];
				arguments[0] = sender;
				arguments[1] = e;
				// --
				
				// Loop through all delegates in the invocationlist to 
				// examine each tarhet object
				foreach(Delegate d in del.GetInvocationList()) 
				{
					// Try to cast the tarhet object to a variable of the type
					// ISynchronizeInvoke. If this succeeds the target object 
					// is probably a control.
					ISynchronizeInvoke syncer = d.Target as ISynchronizeInvoke;
					if (syncer == null) 
					{
						// Cast failed, invoke delegate the regular way.
						d.DynamicInvoke(arguments);							
					} 
					else 
					{
						// Cast succeeded, the target object is a control
						// post the delegate to the main thread
						syncer.BeginInvoke(d, arguments);
					}
				}			
			} // if (del != null)
		} // SyncInvoke	

                                // Event
		public event WorkEvent Work;

                                // Method used from our class to invoke our event.
		private void OnWorkDone(EventArgs e)
		{
			if(null!=Work)
			{
				this.SyncInvoke(Work, this, e);
			}			
		}


Svara

Nyligen

  • 09:09 Vill du köpa medicinska tester?
  • 12:47 Vem beviljar assistansen – kommune
  • 14:17 Någon med erfarenhet av hemstädnin
  • 14:14 Bör man använda sig av en båtförme
  • 14:12 Finns det någon intressant hundblo
  • 14:25 Tips på verktyg för att skapa QR-k
  • 14:23 Tips på verktyg för att skapa QR-k
  • 20:52 Fungerer innskuddsbonuser egentlig

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 569 156
27 952
271 704
14 296
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies