none
Working thread cyclic calls - concept RRS feed

  • Question

  • Hello!
    I have the following requirement, every 60 seconds I have to do something.
    I solved it with thread and used the property Totalseconds.
    With seconds it is not working, 58, 59, 0, 1, 2 and so one.
    The question, can I solve it this way or is there a better solution?
      - With Task.Run ?
      - How can I solve this with a break ?
        Supend is old.
     
    Maybe you can publish 2, 3 examples (with thread and task)?
     And the advantages and disadvantages.
     
     Thank you in advance.

     With best regards Markus
    protected Thread ThreadCycleDataUpload;
    protected ManualResetEvent ThreadCancelDataUpload;
    
    ThreadCancelDataUpload = new ManualResetEvent(false);
    ThreadCycleDataUpload = new Thread(CycleDataUpload);
    
    protected void CycleDataUpload()
    {
    	Stopwatch time = new Stopwatch();
    	time.Start();
    
    	while (!ThreadCancelDataUpload.WaitOne(0))
    	{
    		// Trace.WriteLine($"---A--- {time.Elapsed.Seconds} {time.Elapsed.TotalSeconds}");
    		if (time.Elapsed.TotalSeconds >= 60 )
    		{
    			RequestDataUpload();
    			time.Reset();
    			time.Start();                    
    		}
    		Thread.Sleep(1000);	
    	}

    Monday, March 11, 2019 5:31 PM

Answers

  • As @ritehere suggested, use a Timer, specifically a System.Timers.Timer. Handle the Elapsed event and put your code there. So, something like this:

    private System.Timers.Timer tmrDataUpload = new System.Timers.Timer();
    
    // put this maybe in your constructor, or somewhere that starts your whole process
    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = true; // this will reset the timer and run again in 60 seconds
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        CycleDataUpload();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }
    

    The downside to this, though, is that if your upload process takes more than 60 seconds, you're in trouble. So, if that's a possibility, you should change it to this:

    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = false;
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        tmrDataUpload.Stop();
        
        CycleDataUpload();
        
        tmrDataUpload.Start();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }
    

    Will this work for you, Markus?


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Tuesday, March 12, 2019 1:02 AM
    Moderator
  • As @ritehere suggested, use a Timer, specifically a System.Timers.Timer. Handle the Elapsed event and put your code there. So, something like this:

    private System.Timers.Timer tmrDataUpload = new System.Timers.Timer();
    
    // put this maybe in your constructor, or somewhere that starts your whole process
    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = true; // this will reset the timer and run again in 60 seconds
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        CycleDataUpload();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }

    The downside to this, though, is that if your upload process takes more than 60 seconds, you're in trouble. So, if that's a possibility, you should change it to this:

    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = false;
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        tmrDataUpload.Stop();
        
        CycleDataUpload();
        
        tmrDataUpload.Start();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }

    Will this work for you, Markus?


    ~~Bonnie DeWitt [C# MVP? LOL]


    Some comments:

    First:

    If the OP is using a Windows Form, then, it's strongly recommended the use of System.Windows.Forms.Timer.

    Second:

    It's recommended the use of static event handlers (in this situation) to avoid nasty problems (see below).

    Third:

    You specified as event handler, the protected instance method tmrDataUpload_Elapsed(...), but you did not specify the instance related to it.

    Fourth:

    Inside the protected instance method tmrDataUpload_Elapsed(...), you are calling the protected instance method CycleDataUpload(), but, once more, you did not specify the instance related to it ( CycleDataUpload ).

    Fifth:

    Notice, calling CycleDataUpload() from inside tmrDataUpload_Elapsed(...), is a cross thread operation... :(

    Tuesday, March 12, 2019 3:31 AM

All replies

  • Hello!

    I have the following requirement, every 60 seconds I have to do something.

    Use a timer.

    Monday, March 11, 2019 10:28 PM
  • As @ritehere suggested, use a Timer, specifically a System.Timers.Timer. Handle the Elapsed event and put your code there. So, something like this:

    private System.Timers.Timer tmrDataUpload = new System.Timers.Timer();
    
    // put this maybe in your constructor, or somewhere that starts your whole process
    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = true; // this will reset the timer and run again in 60 seconds
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        CycleDataUpload();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }
    

    The downside to this, though, is that if your upload process takes more than 60 seconds, you're in trouble. So, if that's a possibility, you should change it to this:

    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = false;
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        tmrDataUpload.Stop();
        
        CycleDataUpload();
        
        tmrDataUpload.Start();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }
    

    Will this work for you, Markus?


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Tuesday, March 12, 2019 1:02 AM
    Moderator
  • As @ritehere suggested, use a Timer, specifically a System.Timers.Timer. Handle the Elapsed event and put your code there. So, something like this:

    private System.Timers.Timer tmrDataUpload = new System.Timers.Timer();
    
    // put this maybe in your constructor, or somewhere that starts your whole process
    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = true; // this will reset the timer and run again in 60 seconds
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        CycleDataUpload();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }

    The downside to this, though, is that if your upload process takes more than 60 seconds, you're in trouble. So, if that's a possibility, you should change it to this:

    protected void MyStartupProcess
    {
        tmrDataUpload.Interval = 60000;
        tmrDataUpload.AutoReset = false;
        tmrDataUpload.Elapsed += new System.Timers.ElapsedEventHandler(tmrDataUpload_Elapsed);
        tmrDataUpload.Start();
    }
    protected void tmrDataUpload_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        tmrDataUpload.Stop();
        
        CycleDataUpload();
        
        tmrDataUpload.Start();
    }
    protected void CycleDataUpload()
    {
        while (!ThreadCancelDataUpload.WaitOne(0))
        {
            RequestDataUpload();
        }
    }

    Will this work for you, Markus?


    ~~Bonnie DeWitt [C# MVP? LOL]


    Some comments:

    First:

    If the OP is using a Windows Form, then, it's strongly recommended the use of System.Windows.Forms.Timer.

    Second:

    It's recommended the use of static event handlers (in this situation) to avoid nasty problems (see below).

    Third:

    You specified as event handler, the protected instance method tmrDataUpload_Elapsed(...), but you did not specify the instance related to it.

    Fourth:

    Inside the protected instance method tmrDataUpload_Elapsed(...), you are calling the protected instance method CycleDataUpload(), but, once more, you did not specify the instance related to it ( CycleDataUpload ).

    Fifth:

    Notice, calling CycleDataUpload() from inside tmrDataUpload_Elapsed(...), is a cross thread operation... :(

    Tuesday, March 12, 2019 3:31 AM
  • Hi Bonnie,
    >Will this work for you, Markus?
    I do not have a windows form and yes, it's best to have a timer.
    That works with my thread too, I'm not sure about the
        time.Elapsed.TotalSeconds
        time.Elapsed.Seconds
     
    I think I will choose the timer version.
    Greetings Markus.
    Tuesday, March 12, 2019 5:17 PM
  • Sounds like a plan, Markus!  Glad I could help you a bit!   =0)

    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Wednesday, March 13, 2019 12:10 AM
    Moderator