[c#] Veilig stoppen van een array van threads

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • IStealYourGun
  • Registratie: November 2003
  • Laatst online: 25-08 20:13

IStealYourGun

Доверяй, но проверяй

Topicstarter
Ik zit met een situatie waar ik niet meteen een oplossing voor vindt.
Om mijn code compact en overzichtelijk te houden heb ik een class aangemaakt die zichzelf aanmaakt en in een array van threads plaatst. Deze threads openen files en daarom is het vrij belangrijk dat deze zichzelf veilig afsluiten. Een Abort() of een Interrupt() is dus niet echt een optie aangezien deze de bestanden open laat staan.

C#:
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
class FooClass
    {
        private Thread[] _listOfThreads;
        private int numberOfThreads = 5;

        public void Start()
        {
            for (int i = 0; i < numberOfThreads; i++)
            {
                if ((_listOfThreads[i] == null) || (!_listOfThreads[i].IsAlive))
                {
                    Thread newThread;
                    FooClass fooClass = new FooClass();
                    newThread = new Thread(new ThreadStart(fooClass.Run));
                    newThread.Start();
                    _listOfThreads[i] = newThread;
                }
            }
        }

        private void Run()
        {
                //Open file...
        }
}


Het grote probleem is dat je niet kan communiceren met de FooClass childs anders kon je daar gewoon een functie insteken. De Thread class is ook sealed dus ik kan niet zomaar functies overschrijven of uitbreiden.

Iemand een idee hoe ik dit veilig kan afhandelen, zonder er 2 classes van te maken?

♥ Under Construction ♦ © 1985 - 2013 and counting. ♣ Born to be Root ★ In the end, we are all communists ♠ Please, don't feed me meat


Acties:
  • 0 Henk 'm!

  • Zeebonk
  • Registratie: Augustus 2005
  • Laatst online: 30-07 20:50
Je zal een middel van communicatie tussen de threads moeten aanmaken.

Een simpele optie, maar afhankelijk van de inhoud van de Run methode wel of niet toepasbaar, is het toevoegen van een bool field aan je class en de Run methode uit te breiden met een while (boolField) {}.

Middels een Stop methode zou je vervolgens de bool om kunnen gooien zodat de threads uit de loop springen. Met een listOfThreads[i].Join() vang je ze vervolgens op, zodat je zeker weet dat ze allemaal zijn gestopt.

[ Voor 20% gewijzigd door Zeebonk op 28-05-2012 14:28 ]


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Gewoon je abstractie een niveau hoger leggen en niet met rauwe threads werken.

Kijk eens naar Microsoft's Task Parallel Library (TPL). Het Task Parallism topic op MSDN vertelt je alles wat je moet weten.

Acties:
  • 0 Henk 'm!

  • FlowinG
  • Registratie: Maart 2003
  • Laatst online: 09:30
Je weet dat compacte code niet altijd het meest onderhoudbare code is?
Verder heb je weleens gekeken naar de Task Parallel Library (vanaf .NET 4.0) of een ThreadPool? Het aanmaken van Threads zoals in jouw code is vrij intensief namelijk. Daarnaast is het superlastig om te debuggen omdat op een hele onverwachte plek in je code allerlei threads kunnen ontstaan die niet gemakkelijk te managen zijn. Als je meer van dit soort classes maakt wordt het nog lastiger: het is dan in runtime heel lastig om al die threads te managen waardoor je met een overschot kan komen die je programma alleen maar vertragen...

In jou geval zal ik de methode run onderbrengen in een class die alleen verantwoordelijk is voor file acties. Deze maak je disposable en eventueel met een destructor gooi je resources weg. In het geval van TPL moet je gaan werken met cancellation tokens als je echte controle wilt uitoefenen.

[ Voor 25% gewijzigd door FlowinG op 28-05-2012 15:00 ]


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
FlowinG schreef op maandag 28 mei 2012 @ 14:37:
de Task Parallel Library (vanaf .NET 4.0)
Er is ook een NuGet package met de Mono-versie van TPL gebackport naar .NET 3.5 en alle Silverlight platforms (incl. Windows Phone 7.x). ;)