[VB.NET] Singleton fatsoenlijk disposen

Pagina: 1
Acties:

Onderwerpen


  • Armageddon_2k
  • Registratie: September 2002
  • Laatst online: 01-10 10:45

Armageddon_2k

Trotse eigenaar: Yamaha R6

Topicstarter
Hey mensen,
Ik ben wat aan het expirimenteren met een singelton en loop hierbij tegen een probleem aan.
Het betreft een singelton met daarin een thread, en het probleem zit em in het disposen.
Doordat de thread nu nog doorloopt, wordt er nooit een dispose uitgevoerd. Wat zoveel inhoud dat een applicatie die deze singleton gebruikt, nooit zal afsluiten.

Ik heb al lopen spelen met IDisposable's en finalizers ed. En het is een vaker gezien probleem, maar de oplossingen die ik tegenkom helpen me niet doordat die thread blijft doorlopen.

Om het nu eerst maar op te lossen, doe ik tijdens het disposen van mijn form een aanroep naar de singleton functie DisposeInstance. Maar echt fraai vind ik het niet. Is hier ook een andere oplossing voor?


Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Public Class Singleton

    'The one and only instance of this object.
    Private Shared instance As Singleton
    Private RunThread As Boolean = True

    Protected Sub New(ByVal FileName As String)
        WorkerThread.Start()
    End Sub

    Public Sub DisposeInstance()
        RunThread = False
    End Sub
    
    Public Shared Function GetInstance(ByVal FileName As String) As Singleton
        ' initialize if not already done
        If instance Is Nothing Then
            instance = New Singleton(FileName)
        End If
        ' return the initialized instance of the Singleton Class
        Return instance
    End Function 'Instance

    
    'The magic happens here.
    Public Sub MainLoop()

        While RunThread

        End While

    End Sub
    
End Class


Tijdens het afsluiten van mij form heb ik dan de volgende code:

Visual Basic .NET:
1
2
        Dim MyStupidSingleton As Singleton = Singleton.GetInstance(Log_Filename)
        MyStupidSingleton.DisposeInstance()

[ Voor 6% gewijzigd door Armageddon_2k op 23-02-2012 16:03 ]


  • Paul
  • Registratie: September 2000
  • Laatst online: 20:53
(jarig!)
Geen idee hoe dat met VB.Net precies zit, heb je hier iets aan: MSDN: Thread.VolatileRead Method (System.Threading) ?

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • Armageddon_2k
  • Registratie: September 2002
  • Laatst online: 01-10 10:45

Armageddon_2k

Trotse eigenaar: Yamaha R6

Topicstarter
Paul schreef op donderdag 23 februari 2012 @ 16:11:
Geen idee hoe dat met VB.Net precies zit, heb je hier iets aan: MSDN: Thread.VolatileRead Method (System.Threading) ?
Zou je daar wat over kunnen toelichten, eventueel in een andere taal dan vb mag van mij ook. Want ik lees zo even door de MSDN en een aantal example's heen. Maar ik zie niet hoe ik dit zou moeten toepassen om mijn probleem op te lossen.

  • SaphuA
  • Registratie: September 2005
  • Laatst online: 10-09 22:00
.

[ Voor 98% gewijzigd door SaphuA op 31-01-2022 15:35 ]


  • Armageddon_2k
  • Registratie: September 2002
  • Laatst online: 01-10 10:45

Armageddon_2k

Trotse eigenaar: Yamaha R6

Topicstarter
SaphuA schreef op donderdag 23 februari 2012 @ 16:28:
Heb je al geprobeerd de BackgroundWorker te gebruiken? Die maakt een hoop zaken makkelijker in het gebruik van Threads.
Instant fix :*)
Ben wel benieuwd of er nog een manier is om een singleton met threading.thread netjes te sluiten, maar mijn probleem is in ieder geval opgelost.

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Lijkt me een vrij lelijke fix om IsBackground op true te krijgen. :p Het hangt een beetje er van af wat je in die thread doet of deze zomaar kan worden afgesloten. Als dit zo is dan werkt dit prima, anders moet je bijvoorbeeld een boolean/event zetten om aan te geven dat de thread mag stoppen.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Paul
  • Registratie: September 2000
  • Laatst online: 20:53
(jarig!)
Armageddon_2k schreef op donderdag 23 februari 2012 @ 16:20:
[...]


Zou je daar wat over kunnen toelichten, eventueel in een andere taal dan vb mag van mij ook. Want ik lees zo even door de MSDN en een aantal example's heen. Maar ik zie niet hoe ik dit zou moeten toepassen om mijn probleem op te lossen.
Het probleem is dat je 1 variabele in 2 threads gebruikt. De workerthread houdt waarschijnlijk (op processorniveau) een eigen kopie bij waardoor je de variabele aan moet merken als volatile zodat de compiler en dus je software weet dat het altijd de laatste versie moet hebben.

Ik ken dit probleem vooral van microprocessoren waarbij het probleem optreed als je in je main iets gebruikt en tijdens een interrupt ook; maar het probleem lijkt me vergelijkbaar met jouw probleem :) Omdat je in VB.Net echter geen volatile-keyword hebt moet je het doen door iedere keer dat je die variabele gebruikt VolatileRead en/of VolatileWrite te gebruiken.

Needless to say dat dit impact heeft op de performance; liefst doe je dat dus zo min mogelijk :) Maar zoals gezegd, ik ben niet bekend met threading in .Net, dus het kan zijn dat ik compleet de verkeerde kant op aan het denken ben.

[ Voor 5% gewijzigd door Paul op 24-02-2012 13:43 ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


Acties:
  • 0 Henk 'm!

  • Armageddon_2k
  • Registratie: September 2002
  • Laatst online: 01-10 10:45

Armageddon_2k

Trotse eigenaar: Yamaha R6

Topicstarter
Misschien niet helemaal duidelijk uit mn startpost maar als ik DisposeInstance() vanuit mijn mainform aanroep, dan gaat het wel gewoon goed hoor. Geen enkel probleem.

Alleen ik houd er niet van dat ik zelf nog de DisposeInstance() moet aanroepen. Ik wil dat dit automatisch gebeurt. En om een bijzondere reden, worden er geen disposers/finalizers aangeroepen.

Acties:
  • 0 Henk 'm!

  • Paul
  • Registratie: September 2000
  • Laatst online: 20:53
(jarig!)
Hoe lang heb je dat getest? Je hebt afaik in managed code erg weinig controle over _wanneer_ de GC langskomt en objecten opgeruimd worden :)

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


Acties:
  • 0 Henk 'm!

  • Armageddon_2k
  • Registratie: September 2002
  • Laatst online: 01-10 10:45

Armageddon_2k

Trotse eigenaar: Yamaha R6

Topicstarter
Paul schreef op vrijdag 24 februari 2012 @ 15:58:
Hoe lang heb je dat getest? Je hebt afaik in managed code erg weinig controle over _wanneer_ de GC langskomt en objecten opgeruimd worden :)
Application shutdown, 10 sec wachten. Kan best dat het na een minuut ofzo netjes wordt opgeruimd. Maar daar zit ik niet op te wachten :P

Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 23:27
Armageddon_2k schreef op vrijdag 24 februari 2012 @ 15:51:
[...]


Misschien niet helemaal duidelijk uit mn startpost maar als ik DisposeInstance() vanuit mijn mainform aanroep, dan gaat het wel gewoon goed hoor. Geen enkel probleem.

Alleen ik houd er niet van dat ik zelf nog de DisposeInstance() moet aanroepen.
Een Singleton is bedoeld om één instantie te gebruiken gedurende de lifetime van je applicatie, dus dan zal je toch dat ding toch echt ook zelf een keer moeten stoppen.
Ik wil dat dit automatisch gebeurt.
Tsja dat zou ik ook wel willen, misschien kan de .Net runtime ook meteen de rest van de applicatie even implementeren? ;)
En om een bijzondere reden, worden er geen disposers/finalizers aangeroepen.
Waarschijnlijk omdat het ding een Singleton is gaat ie nooit out of scope. Heb je wel een singleton nodig? Als ik een GetInstance zie met een parameter heb ik al m'n twijfels.

Roomba E5 te koop

Pagina: 1