@@ -150,21 +150,25 @@ private void RecalcGeoObject(object state)
150150 {
151151 // hier wird die eigentliche Arbeit gemacht
152152 go . PrepareDisplayList ( data . Precision ) ;
153- lock ( runningThreads )
154- {
155- runningThreads . Remove ( data . RecalcID ) ; // wirft keine Exception wenn nicht drin
156- // recalcDone hat einen Wert, wenn DoBackgroundRecalcDisplayList alle Objekte in die
157- // Queue gesteckt hat und auf das Ende wartet
158- if ( recalcDone != null && runningThreads . Count == 0 )
159- { // wenn der letzte thread fertig ist, nachdem alle in der Liste stehen
160- // wird recalcDone "signalisiert", d.h. alle Objekte sind jetzt berechnet
161- // und eine neue Displayliste kann schnell hergestellt werden
162- recalcDone . Set ( ) ;
163- }
164- }
165153 }
166154 }
167155 }
156+ // Always remove from runningThreads regardless of cancellation. If a worker exits
157+ // early due to cancellation without removing itself, DoBackgroundRecalcDisplayList
158+ // can block forever on recalcDone.WaitOne() when AbortBackgroundRecalc ran before
159+ // recalcDone was created and therefore could not signal it.
160+ lock ( runningThreads )
161+ {
162+ runningThreads . Remove ( data . RecalcID ) ; // wirft keine Exception wenn nicht drin
163+ // recalcDone hat einen Wert, wenn DoBackgroundRecalcDisplayList alle Objekte in die
164+ // Queue gesteckt hat und auf das Ende wartet
165+ if ( recalcDone != null && runningThreads . Count == 0 )
166+ { // wenn der letzte thread fertig ist, nachdem alle in der Liste stehen
167+ // wird recalcDone "signalisiert", d.h. alle Objekte sind jetzt berechnet
168+ // und eine neue Displayliste kann schnell hergestellt werden
169+ recalcDone . Set ( ) ;
170+ }
171+ }
168172 }
169173
170174 private class RecalcGeoObjectData
0 commit comments