tjo Jag skulle nog gjort följande: fast problemet här verkar vara att det blir något redigt kajko med trådningen. Det var märkligt. nja , resultatet lagras i queryobjectet som i sin tur ligger i en session variabel. SÅ det är page_Load som truggar tråden och det är page_load osm alltid kollar om idDone är satt till true? nej tråden startas av queryobjektet :: sähär funkar det: hum... >frågan är nu , är det ok att dra igång trådar i asp.net? Jag är inte säker på att callbacken körs i en ny tråd, trådar i asp.net?
sitter och meckar lite med vårat statistiksysetm här ,
nu är det så att frågorna vi kör _kan_ ta lång tid ibland
så jag ska visa en progressbar bild medans frågan körs.
progressbar sidan pollar mot vårat queryobjekt för att se om det är färdigt.
queryobejktet lagras i en sessionvariabel (jag vet att det kanske inte är så jäkla snyggt , men det skiter jag i , funkar gör det)
hur som , queryobjektet ska köra frågan i bakgrunden , så just nu gör jag så att queryobjektet drar igång en tråd som startar frågan,, i slutet av tråd metoden så sätter jag en property till true... så att den pollande sidan ska veta att allt är klart..
frågan är nu , är det ok att dra igång trådar i asp.net?
och
hur fasen får man allt att synca fint , om jag inte har någon låsning på grejjorna så funkar det _nästan_ , av någon anlednign så får man resultatet av föregående fråga hela tiden... (null första gången)
har testat med "lock(IsDone)" i slutet på tråden , men då står den bara och tuggar i evig tid , precis som att IsDone aldrig blir satt..
jaja , kanske var lite luddigt beskrivet ,,,
//RogerSv: trådar i asp.net?
1) SKapa en metod som utför frågan (ditt queryobjet).
2) Metoden genererar ett GUID och lagrar detta i en cache på server (ev Databas)
3) Metoden anropar sedan metoden som utför frågan i en ny tråd.
4) GUID:et returneras, en redirect görs till en sida som visar "Vänta.....", GUID:et skickas med i en querystring.
Vänta sidan har en metatag som gör en refresh tex med ett intervall på 5 sec.
När sidan requestas, så använder du GUID:et för att läsa av i cachen på servern (ev Databas) om fråga
har utförts klart eller inte. Om inte så kommer sidan laddas om tills frågan är utförd.
Jag skulle inte placerat "queryobjektet" i en session utan låta den initerias för varje request.
"Queryobjektet" har en metod som tar GUID:et som ett argument och gör en fråga mot cachen på servern (ev databas)
för att se om frågan är utförd eller inte, motoden i sig returnerar true om fågan är utförd.
Eftersom frågan körs i en ny tråd, så är det trådens uppgift att notifier om frågan har utförts.
/Fredrik Normén NSQUARED2
http://www.nsquared2.netSv: trådar i asp.net?
min kod i metoden som körs i tråden ser ut ungefär:
private void RunQuery()
{
DataTable dt=MyDataLayer.ExecuteQuery(this.BuildQuery));
this.Result=dt;
this.IsDone=true; //<-- görs EFTER att resultatet blivit tilldelat..
}
det som händer är att när jag pollar och kollar att IsDone är true , så vet jag att frågan är klar... så långt allt väl..
men när jag sedan läser av .Result , så är den först null... nästa fråga jag kör så är den resultatet från förra frågan..
vilket får mig att tro att något med trådningen under asp.net gör något redigt lattjo med mitt resultat..
//RogerSv: trådar i asp.net?
Dock är min fråga kör du fortfarande session? när uppdaterar du den? i en event metod? och sedan läser du den i Page_Load ? I så fall kommer du inte åt det senaste värdet som sätts om det sättts i din event metod. Då ligger du alltid ett värde efter.
Är du med?
Page_Load
Läs Session()
Onclick_Button(....)
Sätt Session() <--- Denna nås nästa gång du trycker på knappen.
Att det är så är för att Page_Load körs alltid före Onclick_Button i detta fall. Så när du i din Onclick_Button sätter ett värde så ser intte du det i samma veva som sidan laddas om. Då får du det värde du satte sist. (Föregående fång.)
Men det kanske inte är ditt fall. Tänk på att när man använder trådning så kan inte variabler utanför tråden alltid få rätt svar, då du kan nå den innan tråden är klar. Vet ej exakt hur din iplementation ser ut.
Mvh JohanSv: trådar i asp.net?
i pageload på min metarefreshade sida så plockar jag fram queryobjektet ur sessionen , kollar om IsDone är true och istäfall ska jag hämta resultatet från den..
//RogerSv: trådar i asp.net?
Mvh JohanSv: trådar i asp.net?
[Bygg fråga GUI ] sida 1
|
[starta fråga sida] sida 2
skapar och lagrar queryobjektet i en session
queryobjektet startar en tråd internt och tråden kör en metod som pratar med databasen.. i slutet av den metoden så sätts sätts först resultatet och sedan "IsDone" till true
|
[wait page] sida 3
meta refreshar sidan , pageload hämtar queryobjektet ur sessionen och kollar sedan om IsDone är true , är det så så fortsätter vi till nästa sida..
|
[Rapport] sida 4
visa resultat ,, hämtar queryobjektet ur sessionen och hämtar resultatet.
resultatet är dock helt åt ### fel..
gör jag exakt samma sak fast låter sida 2 köra frågan direkt , utan att köra den i en tråd så funkar allt prima..
//RogerSv: trådar i asp.net?
Så tråden körs när objektet ligger i sessionen? Är lite osäker på hur det fungerar i bakgrunden så jag vågar inte säga något om det. Men istället så kan du ju göra som min bror skrev. Du kollar en källa om något är updaterat tills det är det. Din tråd lägger du alltså inte i en session du startar den som den är och låter den spara ner en indikation i datakällan att nu är jag klar typ.
Kan du inte lösa det så?
Mvh JohanSv: trådar i asp.net?
Jag skulle nog se till att använda trådpoolen istället. Om du t.ex. anropar en delegat asynkront så körs det på en tråd från poolen, och sen kan du använda IAsyncResult för att kolla när arbetet är klart.
MSSv: trådar i asp.net?
--Något som ingentligen inte hör hit till 100% men kan vara värt att säg
Om prestanda och skalbarhet spelar stor roll, så använd trådpolen istället för att skapa en egen tråd, skapandet av en egen tråd kräver extra resurser och kan bli kostsamma, .Net trådpolen behöver inte skapa nya trådar på samma sätt som när du skapar en egen tråd för den har redan flera initierade som går att återanvända. Se bara till att inte låsa upp trådar under längre tider, för det kan blocka inkommande request. Jag skulle inte rekommendera asynkrona anrop i ASP.Net och helst undvikt användandet av dom, speciellt om vi inte har möjligheten att frigöra den anropade tråden som gör det asynkrona anropet. Du vinner nämligen inte så mycket på att göra asynkront anrop prestanda mässigt. Om du använder en delegate för att registrera en call back för att processa resultatet från det asynkrona anropet, så kommer call backen köras i en egen tråd från trådpolen. Eftersom du då använder en annan tråd från trådpolen som igentligen borde användas för att processa ett annat request, så har igenltigen bara skapat en ny tråd "switch". I de situtationer då du inte behöver veta svaret från ett metodanrop eller om metoden har utförsts eller inte, använd då "fire and forget" genom att använda OneWay attributet.
--
/Fredrik Normén NSQAURED2
http://www.nsquared2.netSv: trådar i asp.net?
den körs på samma tråd som den asynkrona exekveringen i alla försök jag har gjort.
Men i övrigt håller jag med, trådar är av ondo. Nu är ju asp.nets tråd pool lite annorlunda om man jämför med andra hosts, den har fler trådar i poolen osv.
Men det finns ett antal fler saker som är viktiga att tänka på,
Trådar använder ju thread swtiching, det vill säga att processorn måste byta exekverings fokus från en tråd till en annan när konstant, det är overhead som vi inte vill ha. Den overheaden gör också att om du har två operationer som tar x och y tid, så kommer de båda att ta x + y + n tid, där n representerar tiden det tar för alla dina thread switches (vilket kan vara 1 eller 1000, det finns inget sätt att veta exakt).
Det gör att du i slutändna, prestanda mässigt, får en långsammare applikation.
Nu är CLRn finurligt konstruerad, vilket ställer till det ännu mer. En tråd i .NET behöver inte nödvändigtvis representera en OS tråd utan CLR har sin egen lilla thread switching på gång. Det ställer till det lite, i teorin skulle kunna få overhead från thread switching 2 ggr, en för CLRn och en för OS'et, som tur är löser CLRn det där snyggt och det är bara i extrema fall vi råkar ut för det.
Däremot om vi lyckas trycka upp antalet OS trådar, då kommer vi få större problem, därför att för varje OS tråd min applikation skapar, desto mindre processor tid får resten av mitt system och desto mer thread switching overhead får du för hela ditt operativ system. Det kan i slutändan till och med dra ner en server om man inte är försiktig.
När jag håller kurs i ämnet, så börjar jag alltid med att förklara de här och ett antal andra underliggande tekniska detaljer, plus visa på deadlocks och race conditions, _innan_ jag visar en rad kod hur man nyttjar trådning.
Förstår man inte begrepp som thread switching, os threads, processes, monitors osv; och då menar jag förstå begreppen inte veta vad de handlar om ( alla känner till ordet process tex men vet de vad den gör, hur minnet är isolerat från OS och varför, overhead med interprocess calls osv?); innan man startar sin första tråd, så mycket bekymmer anser jag att de kan ställa till med.