c # - Hvornår/hvordan afregistrerer jeg en RegisteredWaitHandle

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg bruger ThreadPool.UnsafeRegisterWaitForSingleObject (fremover RWFSO) til asynkront at vente på Semaphore. Det returnerer mig en RegisteredWaitHandle, som jeg ikke nemt kan Unregister(). Jeg skal afregistrere disse, fordi håndtag er at henvise til delegaten og dens statsobjekt, og min proces lækker hukommelse med hvert håndtag. Til sidst bliver de færdige, men det tager alt for lang tid og sætter alt for meget pres på GC, der ballonerer min proces s private hukommelsesforbrug op til 1,8GB-området. Jeg gør mange asynkrone anmodninger.


Semaforen bruges til at få adgang til HttpWebRequest s asynkrone implementering: BeginGetRequestStream og BeginGetResponse. Hvis jeg ikke bruger en semafor, fortæller det mig 'ikke nok ledige tråde på tråd pool 'på grund af den moronske måde, hvorpå den blev implementeret. Hvis jeg bruger blokering af primitiver som semaphore.WaitOne(), så vil min trådpulje i sidste ende være dødlåst og intet vil gøre fremskridt.


RWFSO returnerer en RegisteredWaitHandle, men det er ubrugeligt for min kaldtråd, da jeg skal Unregister() dette håndtag kun, når ventetiden er afsluttet; Jeg har intet afbestillingsscenarie. Jeg kan ikke videregive RegisteredWaitHandle eksemplet til min delegerede (via et felt uden for båndet på statsobjektet, der er overført til delegaten), fordi delegaten kunne udfyldes på en anden tråd, før kontrol selv vender tilbage fra RWFSO .


Hvordan gør jeg sikkert og hurtigt Unregister() en RegisteredWaitHandle s når og kun når ventetiden er afsluttet?

Bedste reference


Bare send håndtaget til delegaten via hvilken mekanisme der fungerer for dig. Hvis håndtaget er null ved det tidspunkt, hvor delegaten udfører, skal delegaten dreje om at vente på opgaven. Du skal ikke bekymre dig om den trivielle mængde CPU-tid, der bruges, fordi du bare kan sætte Thread.Yield i løkken. Hvis det plager dig, kan du bruge en lås.


Alternativt kan du afregistrere de håndtag der er der, og lad GC rydde op de få, der tabte løbet.

Andre referencer 1


Hvis du skal binde en tråd, der venter på håndtaget, hvorfor ikke bare gøre HTTP-anmodningen synkront? Hvad du laver, er faktisk at binde to tråde pr. Forespørgsel (hvis jeg forstår din implementering korrekt), mens du bare kører dine anmodninger synkront ville tage en tråd pr. Anmodning (og kunne stadig modereres ved hjælp af en semafor eller en tvunget trådpulje, hvis du nødt til at smøre det).