Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[c#] while Thread.IsAlive

Pagina: 1
Acties:

  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
Ben redelijk vers met C#, en kom met een probleem dat ik niet opgelost krijg.

Ik heb een aplicatie welke op bepaalde tijden wat moet uitvoeren. Om te kijken of het al zo laat is loopt er een thread die elke seconde kijkt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void WorkThreadFunction(object objtime1)
        {

                  DateTime stringtime1 = Convert.ToDateTime(objtime1);
               Begin:
                   if (stringtime1 < DateTime.Now)
                   {
                       Thread.CurrentThread.Abort();

                   }

                   else
                   {
                       Thread.CurrentThread.Join(1000);
                       goto Begin;

                   }           
        }


het probleem is dat niet alleen deze thread slaapt, maar ook mijn hele form..


Zo roep ik hem aan:
code:
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
 private void button2_Click(object sender, EventArgs e)
        {


            for (int i = 0; i < listView1.Items.Count; )
            {
                objtime1 = listView1.Items[0].SubItems[0].Text;

                Worker workerObject = new Worker();
                Thread workerThread = new Thread(WorkThreadFunction);
                // Start the worker thread.
                workerThread.Start(objtime1);
               
                while (workerThread.IsAlive) ;


                login();
   close();
            }

            button1.Enabled = true;
            MessageBox.Show("klaar");


        }


Ik zit hier nu al 2 avonden omheen te werken, maar krijg denk ik niet de juiste termen in google..
Wie kan mij helpen?

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Als je goed had gedegged kon je natuurlijk in 5 seconden zien waar het fout zit.

Deze statement zorgt er uiteraard voor dat alles blijft wachten tot de thread klaar is:
while (workerThread.IsAlive) ;

Daarnaast is het gebruik van goto gewoon een nono.

  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
Dat klinkt idd logisch, Kun je me een tip geven om op de goede weg te komen, want ik zie geen andere oplossing met mijn kennis.

Over de goto, dat is de snelste oplossing met mijn beschikbare kennis.

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Tip: verplaats de while loop naar de thread ;)

  • pedorus
  • Registratie: Januari 2008
  • Niet online
MSDN: Timer Class (System.Windows.Forms) is waarschijnlijk handiger als beginner, dan zit je niet met meerdere threads.

En deze code is natuurlijk niet echt mooi, met onjuist gebruik van witruimte wat je IDE zo voor je kan fixen, een goto in plaats van een while, een join in plaats van sleep, onaangepaste wachttijd (niet-nuttige combinatie tussen busy wait en sleep, je kan gewoon precies lang genoeg wachten), enz.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
Megamind schreef op dinsdag 09 juli 2013 @ 21:42:
Tip: verplaats de while loop naar de thread ;)
Ja dat levert nieuwe problemen op :( want die gebruikt een webbrower element, wat foutmeldingen geeft. ( die ik zo niet bij de hand heb maar had te maken met set thread to STA state

[ Voor 30% gewijzigd door Bill_E op 09-07-2013 22:02 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Nog een tip: verdiep je even in de basics van control structures. Als je dit niet anders dan met een goto uit weet te drukken krijg je ooit nog eens een collega die je in de nacht thuis op komt zoeken. En niet om te scrabblen.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
hey gelukkig doe ik c# voor de hobby. En nog lang niet professioneel ;).

Opmerkingen over een opmaak met regels zijn niet echt relevant, ik heb er een hoop code uitgehaald om uit te drukken wat het probleem was. Die join, was ooit een sleep. Was alleen aan het experimenteren.

Precies lang genoeg wachten is een hele goede opmerking. Zo had ik het nog niet bekeken, maar dat is idd logisch. Die enz hoor ik graag ;)

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Daar is nauwelijks beginnen aan; ik weet ook niet wat je precies probeert te doen. Die potentieel oneindige for-loop zonder gebruik of ophoging van i ziet er bijvoorbeeld heel bijzonder uit. Het omzetten van tijden kun je beter zsm doen, voor als het faalt (niet tijd als string doorgeven). Knoppen en objecten kun je beter een nuttige naam geven. Debuggen kan vast handiger met breakpoints of logging dan msgbox. Threads wil je meestal ergens opslaan voor communicatie. "while (workerThread.IsAlive);" is een busy variant (100% cpu-gebruik) van Thread.Join(), zelden nuttig, en zeker niet om te verplaatsen naar de workerThread zelf. En vast nog meer opmerkingen.

Als ik dit soort code zou zien, dan zou ik het weggooien en opnieuw beginnen. ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
Ik snap je punten, op het opslaan van de threath na. Ben ook al ff met timers aan het spelen.

Eigenlijk is het vrij simpel wat ik wil bereiken, ik heb een invulveld voor een tijd. Die voeg ik toe aan een listview, en daarin worden ze gesoteerd.

Als ik die tijden heb ingevoerd, en ik start de actie, dan moeten er een aantal zaken gebeuren op de ingevoerde tijden. ( komt niet op een miliseconde aan ).

Die actie's had ik eerst in een thread zitten, en dat werkte prima. Nu ben ik het project aan het uitbreiden, en heb ik een webbrowser aan mijn project toegevoegd. Op het moment dat ik die in een thread zet krijg ik foutmeldingen die mijn pet te boven gaan. ( Error HRESULT E_FAIL has been returned from a call to a COM component.)

Om daaromheen te werken zoek ik dus een manier om mijn programma te pauzeren zonder dat alles geheel bevriest..

Opnieuwbeginnen is leuk, maar ik zit op een punt dat ik niet meer weet waarnaar ik moet zoeken.

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Dit is nou een schoolvoorbeeld van waarom we tegenwoording Task<TResult> en aanverwanten hebben.

Ga niet lopen klooien met low level thread operaties als je er geen verstand van hebt, want dan ga je onherroepelijk de mist in.

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 20:13
Wellicht dat de MSDN: Timer Class (System.Windows.Forms) je kan helpen. Interval op een seconde ofzo, geen gedoe met threads.

Roomba E5 te koop


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je kunt inderdaad beter kijken naar de Timers classes ( System.Timers.Timer, System.Windows.Forms.Timer of System.Threading.Timer ). Voor een vergelijking van de verschillende timers: MSDN: Comparing the Timer Classes in the .NET Framework Class Library

Voor het uitvoeren van taken op de achtergrond kun je inderdaad beter kijken naar de TPL waar R4gnax naar verwijst.

Verder zijn er ook genoeg task scheduling libraries beschibaar zoals http://quartznet.sourceforge.net/, voor als je wat complexere scheduling nodig hebt, en geen zin hebt om het wiel opnieuw uit te vinden.

[ Voor 8% gewijzigd door Woy op 10-07-2013 09:55 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • pedorus
  • Registratie: Januari 2008
  • Niet online
R4gnax schreef op woensdag 10 juli 2013 @ 09:02:
Dit is nou een schoolvoorbeeld van waarom we tegenwoording Task<TResult> en aanverwanten hebben.

Ga niet lopen klooien met low level thread operaties als je er geen verstand van hebt, want dan ga je onherroepelijk de mist in.
Dat lost het probleem niet op dat je niet zomaar dingen die door de GUI thread beheert worden in een andere thread kan veranderen. Je zult dan iets als MSDN: Control.Invoke Method (Delegate) (System.Windows.Forms) moeten gebruiken. Maar als je de GUI thread blokkeert, zoals met "while (workerThread.IsAlive);", werkt zelfs dat niet. Het is vanwege COM ook zelfs niet toegestaan om dat te doen (technisch ingewikkeld verhaal), ik gok dat dat de foutmelding veroorzaakt die TS krijgt.

Vandaar dat de windows forms timer vast handiger is.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
pedorus schreef op woensdag 10 juli 2013 @ 10:52:
[...]
Vandaar dat de windows forms timer vast handiger is.
Persoonlijk zou ik eerder naar een System.Timers.Timer kijken, puur omdat die niet afhankelijk is van WinForms maar wel synchronisatie met de UI thread heeft.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Woy schreef op woensdag 10 juli 2013 @ 10:58:
[...]

Persoonlijk zou ik eerder naar een System.Timers.Timer kijken, puur omdat die niet afhankelijk is van WinForms maar wel synchronisatie met de UI thread heeft.
Inderdaad, dat is een beter idee, mits SynchronizingObject gezet is.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
pedorus schreef op woensdag 10 juli 2013 @ 10:52:
Dat lost het probleem niet op dat je niet zomaar dingen die door de GUI thread beheert worden in een andere thread kan veranderen.
Dat lost het probleem wel op, mits je Tasks gebruikt zoals ze bedoeld zijn. Een Task maak je aan, deze doet werk op de achtergrond, geeft gegevens terug aan de UI thread en daarna kun je op de UI thread de daadwerkelijke wijzigingen maken aan je controls.

Maar goed; als je enkel een simpele heartbeat nodig hebt en niet daadwerkelijk werk op de achtergrond wilt plaats laten vinden, kun je inderdaad net zo goed een system timer gebruiken.

[ Voor 18% gewijzigd door R4gnax op 10-07-2013 21:02 ]


  • pedorus
  • Registratie: Januari 2008
  • Niet online
of zelfs beter, testje:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
        private void Form1_Load(object sender, EventArgs e)
        {
            Task.Factory.StartNew(() => Thread.Sleep(5000),
             //need to use separate thread for sleep (is wrong in pool)
                TaskCreationOptions.LongRunning). //or await Task.Run(...)
                ContinueWith((_) => MessageBox.Show("after 5s - what's wrong?"),
                TaskScheduler.FromCurrentSynchronizationContext());
            var timer = new System.Timers.Timer(5000) {AutoReset = false,
                SynchronizingObject = this};
            timer.Elapsed += (_, _2) => MessageBox.Show("after 5s - ok");
            timer.Start();
        }

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
Ok ik ga me eens inlezen op de tasks, bedankt voor de pointers.

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Bill_E schreef op woensdag 10 juli 2013 @ 22:38:
Ok ik ga me eens inlezen op de tasks, bedankt voor de pointers.
Dat lijkt me niet een geweldig onderwerp om mee te beginnen. Als beginnend programmeur is het denk ik het handigst om het voorlopig bij 1 thread te houden..

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
Dus eerst timers?

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Of zelfs eerst andere basisvaardigheden leren van programmeren ;) In ieder geval komen Timers voor Tasks/Threads.

Voor de duidelijkheid, het voorbeeld hierboven kun je beter negeren en is meer een voorbeeld om aan te tonen dat er een verschil is, wat uitvalt in het voordeel van System.Timer. Het lijkt me ook minder handig om per Timer een aparte thread aan te maken bijvoorbeeld, en in theorie kun je de benodigde aparte threads met Tasks zelfs niet afdwingen (in de praktijk doet LongRunning dit wel).

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
Je had gelijk, gebruik van timers is vrij simpel.

nu heb ik dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 {
            if (listViewTask1.Items.Count > 0)
            {
                DateTime d1 = DateTime.Now;
                DateTime d2 = Convert.ToDateTime(listViewTask1.Items[0].SubItems[0].Text);
                TimeSpan t = d1 - d2;
                double time = t.TotalMilliseconds;
                time = time * -1;

                var timer = new System.Timers.Timer(time)
                {
                    AutoReset = false,
                    SynchronizingObject = this
                };

                timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
                timer.Start();

            }
        }


Hier zitten nog een paar rare dingen in, de tijd in de listview wordt een string, ik gok dat dit ook als echte datetime erin gezet kan worden. Dat zoek ik de volgende keer wel uit, ook is mijn manier van een negatief getal een positief getal wellicht wat orthodox, maar dit leek mij het gemakelijkste zonder er lang over na te denken.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Bill_E:
ook is mijn manier van een negatief getal een positief getal wellicht wat orthodox, maar dit leek mij het gemakelijkste zonder er lang over na te denken.
Orthodox? Baanbrekend eerder :P.

Nog maar een tip.
a - b = -(b - a)
en:
a * -1 = -a

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Of in het geval dat je niet weet welke van de twee groter is, en dus niet zeker weet of het resultaat positief of negatief is: MSDN: Math.Abs Method (System)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Bill_E
  • Registratie: September 2007
  • Laatst online: 27-10 14:04
drm schreef op vrijdag 12 juli 2013 @ 09:39:
[...]
Orthodox? Baanbrekend eerder :P.

Nog maar een tip.
a - b = -(b - a)
en:
a * -1 = -a
Ik heb zo het gevoel dat je baanbrekend niet als iets positiefs ziet.

Even iets anders, ik plaats de vragen nu hier en vind het tof dat mensen de tijd nemen om positieve input te leveren aan dit topic, maar ergens heb ik het gevoel dat tweakers niet helemaal het juiste platform is.

Engelse alternatieven ken ik wel,zoals stackoverflow.com, maar Nederlandse niet.
Pagina: 1