[C#] Threading vanuit service

Pagina: 1
Acties:

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Hallo,

Ik wil graag een service die een timer heeft.
Die timer moet bijvoorbeeld om de 5 seconden afgaan.

als de timer afgaat wil ik een langdurende operatie starten. Nu kan het zijn dat operatie X te lang duurt en dan wil ik de operatie aborten.

Ik dacht er dus aan om deze operatie in een aparte thread te laten lopen. Ik wil echter maar 1 thread tegelijk hebben lopen en deze op elkaar laten wachten. Dus als de timer iedere 5 seconden afgaat en de task duurt bijvoorbeeld 6 seconden wil ik dat ze als het ware gequeued worden (zoals de timer werkt als ik geen threading gebruik).

Maar om toch te kunnen aborten denk ik dat ik dit met threading moet doen. Hoe kan ik dit voor elkaar krijgen?

alvast bedankt.


ik heb nu:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public Form1()
{
            InitializeComponent();
            _myClass = new MyClassThatDoesSomethingAndHasAState();
            _thread = new Thread(new ThreadStart(Run));
}

 private void Run()
 {
            _myClass.DoSomething();  
  }


 private void timer1_Tick(object sender, EventArgs e)
 {
            
      _thread.Start();
           
 }


De timer wordt gestart door een button click.

Als nu de timer afgaat dan krijg ik een exception dat de thread niet opnieuw gestart kan worden.Ik neem aan dat er methodes zijn om de thread opnieuw af te trappen.
Is dit wel the way to go? of moet ik toch iedere timer_tick een

C#:
1
_thread = new Thread(new ThreadStart(Run));


Ik dacht namelijk dat er dan steeds een nieuwe thread gestart wordt en ik wil echter maar 1 thread zodat de tasks op elkaar gaan wachten.

ik hoop dat mijn bedoeling een beetje duidelijk is.

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • mulder
  • Registratie: Augustus 2001
  • Nu online

mulder

ik spuug op het trottoir

Deze was ik ooit eens tegengekomen: QueuedBackgroundWorker , misschien handig ;)

oogjes open, snaveltjes dicht


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 30-11 11:20

voodooless

Sound is no voodoo!

Ik denk dat je het beter anders kunt aanpakken:

- neem een lijst als fifi queue waar je je opdrachten op zet iedere x minuten.
- laat een enkele eeuwig (natuurlijk wel aborable) thread de queue afwerken. Als de queue leeg is laat je de thread slapen tot je hem weer wakker maakt omdat er weer wat in de queue zit. op dat moment kun je ook checken hoelng de actieve opdracht bezig is, en je kan deze annuleren als deze te lang bezig is (hoe, moet je maar in de opdracht regelen).

Dit lijkt me wel een overzichtelijke en efficiente methode. Er zijn vast nog wel talloze andere oplossongen.

Do diamonds shine on the dark side of the moon :?


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Dit is misschien ook een oplossing.
Ik vraag me echter af hoe ik zonder queue, dus gewoon op een bepaalde interval een methode aan kan roepen op 1 thread zodat ik die thread kan aborten als dat nodig is. (als er een andere manier is om een uitvoerende methode te aborten is dat ook een idee hoor! Het is niet zo dat ik persee threading wil.)

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • barfieldmv
  • Registratie: Maart 2004
  • Laatst online: 10-10 12:36
4of9 schreef op donderdag 19 april 2007 @ 08:34:
Dit is misschien ook een oplossing.
Ik vraag me echter af hoe ik zonder queue, dus gewoon op een bepaalde interval een methode aan kan roepen op 1 thread zodat ik die thread kan aborten als dat nodig is. (als er een andere manier is om een uitvoerende methode te aborten is dat ook een idee hoor! Het is niet zo dat ik persee threading wil.)
Je kan je code gewoon uitvoeren in de timer_tick event handler dan moet je wel beginnen met:

private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
//functie code
timer1.Enabled = true;
}

Nu gaat de timer pas weer lopen als je funtie volledig is uitgevoerd.

  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Dat gaat niet werken aangezien de TS expliciet wil kunnen cancellen.\

@4of9
Misschien dat je een combinatie kunt maken tussen de queue die voodooless voorstelt en de WaitHandle class.

Nu met Land Rover Series 3 en Defender 90


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
Gaat je timertick niet af ongeacht of je met de vorige al wel klaar was? Wat is je langdurende operatie dan? Is dit niet één of ander loopje die meerdere korte operaties doet? Dan zou je middels een boolean die je controleert die operatie kunnen laten afkappen, opnieuw op true zetten en je nieuwe operatie starten.

Edit: sorry, je verhaal is niet echt duidelijk met wanneer er gewacht moet worden en wanneer er afgebroken moet worden en op welke manier dit automagisch moet gaan.

[ Voor 21% gewijzigd door riezebosch op 19-04-2007 08:55 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • mulder
  • Registratie: Augustus 2001
  • Nu online

mulder

ik spuug op het trottoir

4of9 schreef op donderdag 19 april 2007 @ 08:34:
Dit is misschien ook een oplossing.
Ik vraag me echter af hoe ik zonder queue, dus gewoon op een bepaalde interval een methode aan kan roepen op 1 thread zodat ik die thread kan aborten als dat nodig is. (als er een andere manier is om een uitvoerende methode te aborten is dat ook een idee hoor! Het is niet zo dat ik persee threading wil.)
Dan zou je gewoon een boolean kunnen bijhouden. Je checkt in je methode of deze door een andere functie op true of false is gezet.

oogjes open, snaveltjes dicht


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Om het wat te verduidelijken:

mijn timer (service) roept een methode aan (in een aparte class lib). De methode handeld een x aantal dingen af. (http request, parsen, files schrijven, een queue afhandelen etc. etc.) ergens tijdens dit process kan dit ding blijven hangen in een exceptioneel geval (als het goed is niet), en omdat het een service is moet hij ten alle tijden door gaan. De service moet de voortgang kunnen monitoren. Dus hoe lang is dit process al aan het lopen en vind de service dat het te lang duurt, cancel dan de huidige operatie en start opnieuw. Dit is even heel globaal wat er moet gaan gebeuren.

De timer gaat idd gewoon iedere keer af maar zal verder niets doen als het huidige process een busy vlag heeft gezet (ze wachten dus op elkaar). Alleen gedurende het process kan ik niet gaan pollen oid. Ik wil dus extern kunnen cancellen (vandaar dat ik aan een thread dacht die het process uitvoert).

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Tepel
  • Registratie: Juni 2006
  • Laatst online: 17-08-2024
Is een threadpool dan misschien iets. Volgens mij kan je daarbij de minimale grootte en maximale grootte instellen. Zet beide op 1 en voila :)
Misschien niet het doel van een threadpool maar het werkt iig wel dunkt me

0x7F


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ik heb nu het volgende:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void _timer_Tick(object sender, EventArgs e)
        {
            Run();
        }


        public void Run()
        {
            txtBox.AppendText("Timer tick @ " + System.DateTime.Now.ToString() + "\r\n");

            if (!_myClass.Busy)
            {
                _thread = new Thread(new ThreadStart(_myClass.DoSomething));
                _thread.Start();
            }

            txtBox.AppendText("Last runTime: " + _myClass.LastRun + "\r\n");
        }


dit lijkt te werken, alleen heb ik nog een vraag:

Kan dit mis gaan? (ik heb niet zo'n ervaring met threading).
blijven de threads bestaan of worden deze zelf opgeruimd? Moet ik nog met andere dingen rekening houden? (thread safety etc.)

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

_thread wordt nu bij elke keer dat Run() wordt aangeroepen overschreven maar die thread wordt niet gestopt.

Je kunt denk ik beter zoiets doen:
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
private Thread thread;
private Runner runner;
protected void timer1_Tick(object sender, EventArgs e)
{
    this.Run();
}

private void Run()
{
    if(this.thread != null)
    {
        if(this.thread.ThreadState == ThreadState.Running)
        {
            // De thread is nog bezig, aborten dus
            this.thread.Abort();
        }
    }

    this.runner = new Runner();
    this.thread = new Thread(new ThreadStart(this.runner.Run));
    this.thread.Start();
}

public class Runner
{
    public void Run()
    {
        try
        {
            // Doe hier dingen
        }
        catch(ThreadAbortException tx)
        {
            // De thread is aborted
        }
        catch(Exception ex)
        {
            // Andere fouten
        }
    }
}


De Run() method kijkt eerst of de thread nog bezig is en abort hem wanneer nodig.

[ Voor 6% gewijzigd door MTWZZ op 20-04-2007 09:10 ]

Nu met Land Rover Series 3 en Defender 90

Pagina: 1