-3

I wrote a code to update DDNS which works fine. I now need to run this code every n minutes: how would I go doing that?

I tried using:

while (true)
{
    this.DoMyMethod();
    Thread.Sleep(TimeSpan.FromMinutes(1));
}

and I am still having some trouble. What is the best way to run this task every n minutes?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Windows.Forms;
using System.Timers;

namespace GoogleDDNS
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (username.Text == "")
            {
                System.Windows.MessageBox.Show("Please enter the username");
                username.Focus();
                return;
            }
            if (password.Text == "")
            {
                System.Windows.MessageBox.Show("Please enter the password");
                password.Focus();
                return;
            }
            if (subdomain.Text == "")
            {
                System.Windows.MessageBox.Show("Please enter the subdomain");
                subdomain.Focus();
                return;
            }

            var client = new WebClient { Credentials = new NetworkCredential(username.Text, password.Text) };
            var response = client.DownloadString("https://domains.google.com/nic/update?hostname=" + subdomain.Text);

            responseddns.Content = response;

            Properties.Settings.Default.usernamesave = username.Text;
            Properties.Settings.Default.passwordsave = password.Text;
            Properties.Settings.Default.subdomainsave = subdomain.Text;

            Properties.Settings.Default.Save();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            username.Text = Properties.Settings.Default.usernamesave;
            password.Text = Properties.Settings.Default.passwordsave;
            subdomain.Text = Properties.Settings.Default.subdomainsave;
        }
    }
}
smn.tino
  • 2,272
  • 4
  • 32
  • 41
Saud Iqbal
  • 375
  • 1
  • 4
  • 15
  • `I searched stackoverflow but none of the solution seems to work.` Unless the post had a lot of negative votes, I would not assume they dont work or were wrong – Ňɏssa Pøngjǣrdenlarp Aug 05 '18 at 21:47
  • `while(true) { this.DoMyMethod(); Thread.Sleep(TimeSpan.FromMinutes(1)); }` What didn't work about that? – mjwills Aug 05 '18 at 21:48
  • what is the exact method you are trying to run? – smn.tino Aug 05 '18 at 21:52
  • use a timer that ticks off every minute, https://stackoverflow.com/questions/1142828/add-timer-to-a-windows-forms-application – kenny Aug 05 '18 at 22:15
  • 1
    Run your console application from windows task scheduler. Separate schedule concern from your application concern. If you really want to do it in your code consider https://www.hangfire.io/ – Michael Freidgeim Aug 05 '18 at 22:32
  • Get familiar with Tasks, async methods and await keyword. This example can be helpful. https://stackoverflow.com/questions/14455293/how-and-when-to-use-async-and-await You can create new Task which would be responsible for running another Task every particular amount of time. – Falcon Aug 05 '18 at 22:15

5 Answers5

2

Why not using System.Threading.Timer to do so?

From the Microsoft documentation, say you have the following sample class:

class StatusChecker
{
    private int invokeCount;
    private int maxCount;

    public StatusChecker(int count)
    {
        invokeCount  = 0;
        maxCount = count;
    }

    // This method is called by the timer delegate.
    public void CheckStatus(Object stateInfo)
    {
        AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
        Console.WriteLine("{0} Checking status {1,2}.", 
            DateTime.Now.ToString("h:mm:ss.fff"), 
            (++invokeCount).ToString());

        if (invokeCount == maxCount)
        {
            // Reset the counter and signal the waiting thread.
            invokeCount = 0;
            autoEvent.Set();
        }
    }
}

Then you can create a Timer to run CheckStatus every n seconds, like:

// Create an AutoResetEvent to signal the timeout threshold in the
// timer callback has been reached.
var autoEvent = new AutoResetEvent(false);
var statusChecker = new StatusChecker(5);

// creates a Timer to call CheckStatus() with autoEvent as argument,
// starting with 1 second delay and calling every 2 seconds.
var stateTimer = new Timer(statusChecker.CheckStatus, autoEvent, 1000, 2000);
autoEvent.WaitOne();
smn.tino
  • 2,272
  • 4
  • 32
  • 41
0

Have a look at this. I recall a colleague using it a while ago:

FluentScheduler - [Project Site]

Usage:

// Schedule an IJob to run at an interval
Schedule<MyJob>().ToRunNow().AndEvery(2).Minutes();

Will fulfill your need.

PmanAce
  • 4,000
  • 2
  • 24
  • 29
  • This is a link-only answer. Please [read this](https://meta.stackexchange.com/a/8259/133351) to understand why this shouldn't happen on SO. – spender Aug 05 '18 at 22:06
  • I didn't include code because I've never used it and quite frankly, why would I copy paste code from the link? – PmanAce Aug 05 '18 at 22:55
  • Because if the link goes down this answer is then useless, which happens a lot – Aaron Jordan Oct 14 '20 at 17:16
0

i use timer, the code is

using System;
using System.Net;
using System.Timers;

static void Main(string[] args)
        {
            Console.WriteLine("The system is start at {0}", DateTime.Now);
            Timer t = new Timer(10000);
            t.Enabled = true;
            t.Elapsed += T_Elapsed;
            Console.ReadKey();

        }
        private static void T_Elapsed(object sender, ElapsedEventArgs e)
        {
            //write your code
        }
0

This is what fixed for me.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Windows.Forms;
using System.Timers;

namespace GoogleDDNS
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (username.Text == "")
            {
                System.Windows.MessageBox.Show("Please enter the username");
                username.Focus();
                return;
            }
            if (password.Text == "")
            {
                System.Windows.MessageBox.Show("Please enter the password");
                password.Focus();
                return;
            }
            if (subdomain.Text == "")
            {
                System.Windows.MessageBox.Show("Please enter the subdomain");
                subdomain.Focus();
                return;
            }

            var client = new WebClient { Credentials = new NetworkCredential(username.Text, password.Text) };
            var response = client.DownloadString("https://domains.google.com/nic/update?hostname=" + subdomain.Text);
            //MessageBox.Show(response);
            responseddns.Content = response;



            Properties.Settings.Default.usernamesave = username.Text;
            Properties.Settings.Default.passwordsave = password.Text;
            Properties.Settings.Default.subdomainsave = subdomain.Text;
            //Properties.Settings.Default.intervalsave = interval.Text;
            Properties.Settings.Default.Save();


        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            username.Text = Properties.Settings.Default.usernamesave;
            password.Text = Properties.Settings.Default.passwordsave;
            subdomain.Text = Properties.Settings.Default.subdomainsave;
            //interval.Text = Properties.Settings.Default.intervalsave;


            System.Windows.Forms.Timer MyTimer = new System.Windows.Forms.Timer();
            MyTimer.Interval = (1 * 60 * 1000); // 45 mins
            MyTimer.Tick += new EventHandler(MyTimer_Tick);
            MyTimer.Start();

        }
        private void MyTimer_Tick(object sender, EventArgs e)
        {
            var client = new WebClient { Credentials = new NetworkCredential(username.Text, password.Text) };
            var response = client.DownloadString("https://domains.google.com/nic/update?hostname=" + subdomain.Text);
            //MessageBox.Show(response);
            responseddns.Content = response;
            //this.Close();
        }

    }
}
Saud Iqbal
  • 375
  • 1
  • 4
  • 15
0

somwhere met this code

class Program
{
    static void Main(string[] args)
    {
        int Interval = 5;

        CancellationTokenSource cancellation = new CancellationTokenSource();
        Console.WriteLine("Start Loop...");
        RepeatActionEvery(() => Console.WriteLine("Hi time {0}",DateTime.Now), TimeSpan.FromMinutes(Interval), cancellation.Token).Wait();
        Console.WriteLine("Finish loop!!!");


    }

    public static async Task RepeatActionEvery(Action action, TimeSpan interval, CancellationToken cancellationToken)
    {
        while (true)
        {
            action();
            Task task = Task.Delay(interval, cancellationToken);

            try
            {
                await task;
            }

            catch (TaskCanceledException)
            {
                return;
            }
        }
    }
}
Shaybakov
  • 618
  • 7
  • 9