Hej
Jag håller på med ett flertrådat projekt i Compact Framework (VS.NET final Beta) och har problem med att programmet ibland hänger sig lock. lock använder jag på hashtables i programmet.
Ex
lock(myHashtable.SyncRoot)
{
myHashtable.add(...);
}
Jag vet inte vad det beror på och vet inte vart jag skall börja leta...
Tacksam för hjälp!
Lär dig använda debuggern när problemet händer. Titta i threads-rutan (Debug-menyn, Windows, Threads) och undersök callstack för respektive thread (Debug-menyn, Windows, Callstack).
Har du flera hashtabeller som du skyddar? Tar du flera lås samtidig, dvs typ:
lock(ht1) {
lock (ht2) {
// blaha
}
}
Se isåfall till att du alltid tar låsen i samma ordning från alla ställen.
Vad är det som gör att du behöver ha flera trådar?
Hej
Tack för callstack-tipset.
Jag har flera hashtabeller jag skyddar, men samma klass. Följande finns alltså inte:
kod:--------------------------------------------------------------------------------lock(ht1) {
lock (ht2) {
// blaha
}
}--------------------------------------------------------------------------------
Jag har en kommunikationsklass som via sockets pollar vissa värden på en server. Därifrån skickas det events till businesslagret och vidare till UI't.
Du får gärna komma med fler tips, för jag har inte löst problemet än.
> Jag har flera hashtabeller jag skyddar, men samma klass...
Inte helt på det klara med vad du menar, det du skriver ovan säger inte så mycket om hur du tar låsen.
Har jag förstått följande rätt? Du har en klass som innehåller flera hashtabeller. Men du har inga nästlade kritiska sektioner (dvs förekommer aldrig att du gör lock på en tråd som redan är inne i ett annat lock-statement)?
Ta ett papper och rita upp dina trådar och hur de tar lås, du måste vara helt på det klara med i vilken ordning låsen tas och på pappret bevisa att det inte finns någon risk för deadlock. Finns risken för deadlock, kommer deadlock att uppstå förr eller senare. Enligt min erfarenhet löser man oftast sådana här problem genom att skaffa sig en klar bild av flödet i programmet.
Det är väldigt svårt att säga mer utan att titta på din kod. Du måste gå igenom varje tråd och titta vilka som väntar. För de trådar som väntar, fundera på vilka trådar som är potentiella ägare av låsen.
Att explicit skapa trådar i .Net är nästan alltid onödigt, när du jobbar med sockets är asynkron I/O att föredra, det finns ganska bra exempel på gotdotnet.com om detta.
Ok, skall försöka förklara upplägget lite bättre och varför jag (tror jag) behöver trådar.
Jag har ett UI med flera forms. De olika formsen är intresserade av olika värden (med olika intervall) som finns att hämta på en server.
Jag har en klass som har en hashtable med symboler (de som skall pollas). Det finns en tråd som itererar listan och skickar vidare till socketklassen om det är dags. Klassen har en Add metod, en Remove metod och ett event som UI't kollar av. Den kollar oxå av ett event från socketklassen och vidarebefodrar detta genom sitt event.
Socketklassen har en metod skickar meddelanden och en tråd som gör receive och skickar event.
Det här var en något förenklad version (det finns bla en klass emellan UI och "symbolklassen"), men du får nog en hyfsad bild ändå.
ok, hinner inte kolla så mycket nu. Men om du bara har en tråd som modifierar i hashtabellen behöver du inte låsa den. System.collections.Hashtable hanterar en skrivare och flera samtidiga läsare, läs mer i MSDN. Däremot kan du få problem med iterationen om en modifiering görs samtidigt. Du måste hantera något exception som kan kastas, har för mig att iteratorns MoveNext kastar InvalidOperationException isåfall, och du bör då fånga det och börja om itereringen. Jag antar (?) att dina upptateringar inte görs särskilt ofta så det blir något problem, men du bör förstås ändå hantera läget.
I ett event kan Hashtablen modifieras genom att en item tas bort och det är inte samma tråd.