C# Timer WinForms

Markus Freitag 3,786 Reputation points
2022-04-26T10:43:54.263+00:00

Hello,

 public System.Threading.Timer AsyncProgramChangeTimer = null;
        public void MyStartTimer()
        {
            lock (this)
            {
                AsyncProgramChangeTimer = new System.Threading.Timer((o) =>
                {
                    if (ProgramChangeDone == false)
                    {
                        //do whatever
                        Trace.WriteLine("Timer was coming!!!");
                        Action<string> DelegateTeste_ModifyText = THREAD_MOD;
                        Invoke(DelegateTeste_ModifyText, $"Timer was coming!!! {DateTime.Now}");
                        AsyncProgramChangeTimer.Change(2000, Timeout.Infinite);
                    }
                    else
                    {
                        Trace.WriteLine("Timer no repeat!!!");
                    }
                }, null, 0, Timeout.Infinite);
            }
        }


 private void THREAD_MOD(string test)
        {
            txtStatus.Text += Environment.NewLine + test;
        }


  private void btnStopTimer_Click(object sender, EventArgs e)
        {
            ProgramChangeDone = !ProgramChangeDone;
            MyStartTimer();
        }

My goal.

A) Action or Func
How do I have to write it if I want a return value?

How do I have to write it if I want to have one return value and two passing parameters?

How do I have to write it if I want to have no return value and three passing parameters?

B) Lock
Do I need the lock so no one can access it?

C) Via a button I would like to switch the timer monitoring on or off.

D) Invoke or Dispatcher ?
Update the controls, which mechanism is correct?
Is this correct in my example?

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,869 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,615 questions
0 comments No comments
{count} votes

Accepted answer
  1. Jack J Jun 24,491 Reputation points Microsoft Vendor
    2022-04-27T03:18:47.34+00:00

    @Markus Freitag , Welcome to Microsoft Q&A,

    A:
    Action delegate doesn't return the value and Func delegate can return one result.

    Example:

    (no parameter and return one value)

     Func<string> delegatechangetest = Changetext;  
     string result = delegatechangetest();  
      
      private string Changetext()  
            {  
                string result = Environment.NewLine+sometext;  
                return result;    
            }  
    

    (Two parameters and return one value)

     Func<string, string, string> delegatechangetest = Changetext;  
      string result = delegatechangetest($"Timer was coming!!! {DateTime.Now}", "yes");  
      
     private string Changetext(string test1, string test2)  
            {  
                string result = Environment.NewLine + test1 + test2;  
                return result;    
            }  
    

    B:
    Yes, you could use lock to stop any other thread to acquire the lock until the lock is released.

    C:
    Please try the following code to use a button to stop or start the timer:

    private void button1_Click(object sender, EventArgs e)  
            {  
                ProgramChangeDone = !ProgramChangeDone;  
                if(AsyncProgramChangeTimer==null)  
                {  
                    MyStartTimer();  
                }  
                else  
                {  
                    AsyncProgramChangeTimer.Change(Timeout.Infinite, Timeout.Infinite);  
                    AsyncProgramChangeTimer = null;  
                }  
                      
            }  
    

    D:
    You could use Invoke or Dispatcher both to update the control:

    Invoke:

     Func<string, string, string> delegatechangetest = Changetext;  
     string result = delegatechangetest($"Timer was coming!!! {DateTime.Now}", "yes");  
     txtStatus.Invoke((MethodInvoker)delegate { txtStatus.Text += result; });  
    

    Dispatcher:

    Func<string, string, string> delegatechangetest = Changetext;  
     string result = delegatechangetest($"Timer was coming!!! {DateTime.Now}", "yes");  
      Dispatcher dispUI = Dispatcher.CurrentDispatcher;  
      DispatcherOperation dispatcherOperation = dispUI.BeginInvoke(DispatcherPriority.Normal, (MethodInvoker)delegate { txtStatus.Text += result; });  
    

    I think your code example is enough to get what you want except the button to start or stop the timer.
    Full completed code example:( Use Function delegate:)

    public System.Threading.Timer AsyncProgramChangeTimer = null;  
    public void MyStartTimer()  
    {  
        lock (this)  
        {  
            AsyncProgramChangeTimer = new System.Threading.Timer((o) =>  
            {  
            if (ProgramChangeDone == false)  
            {  
                //do whatever  
                Console.WriteLine("Timer was coming!!!");  
                //Action<string, string> DelegateTeste_ModifyText = THREAD_MOD;  
                //Invoke(DelegateTeste_ModifyText, $"Timer was coming!!! {DateTime.Now}", "yes");  
                Func<string, string, string> delegatechangetest = Changetext;  
                string result = delegatechangetest($"Timer was coming!!! {DateTime.Now}", "yes");  
                txtStatus.Invoke((MethodInvoker)delegate { txtStatus.Text += result; });  
                    //Dispatcher dispUI = Dispatcher.CurrentDispatcher;  
                    //DispatcherOperation dispatcherOperation = dispUI.BeginInvoke(DispatcherPriority.Normal, (MethodInvoker)delegate { txtStatus.Text += result; });->Use dispatcher to update control  
                AsyncProgramChangeTimer.Change(2000, Timeout.Infinite);  
    
    
    
                }  
                else  
                {  
                    Console.WriteLine("Timer no repeat!!!");  
                }  
            }, null, 0, Timeout.Infinite);  
        }  
    }  
    public bool ProgramChangeDone = true;  
    
    private string Changetext(string test1, string test2)  
    {  
        string result = Environment.NewLine + test1 + test2;  
        return result;    
    }  
    private void THREAD_MOD(string test1,string test2)  
    {  
        txtStatus.Text += Environment.NewLine + test1+test2;  
    }  
    
    private void button1_Click(object sender, EventArgs e)  
    {  
        ProgramChangeDone = !ProgramChangeDone;  
        if(AsyncProgramChangeTimer==null)  
        {  
            MyStartTimer();  
        }  
        else  
        {  
            AsyncProgramChangeTimer.Change(Timeout.Infinite, Timeout.Infinite);  
            AsyncProgramChangeTimer = null;  
        }  
              
    }  
    

    Best Regards,
    Jack


    If the answer is the right solution, please click "Accept Answer" and upvote it.If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful