Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I trigger a method to run after x seconds?

Tags:

c#

timer

I am working on a C# Windows Forms application where I need the method to pause for 30 seconds until it continues on to the next line of code. I have tried Thread.Sleep() which wasn't suitable for this application and I've understood that I should use some sort of timer instead. I have searched a lot but I can't figure out how to implement timers.

My code is below and could anyone show me how I should implement the timer. I have made a comment on where I want the method to pause.

private void start_Vid_Click(object sender, EventArgs e)
{
    if (video.State != StateFlags.Running)
    {
        viewport.Visible = true;
        video.Play();
    }

    //Here I want to wait 30 seconds until the next line of code is triggered

    viewport.Visible = false;
    viewport2.Visible = true;
    pictureBox1.Visible = true;
    start_Webc(); 
    video2.Play();
}
like image 630
user1881847 Avatar asked Dec 06 '12 09:12

user1881847


People also ask

How do you run codes after a few seconds?

Setting up code to run later # The setTimeout() method accepts two arguments: the function to run, and how long to wait (in milliseconds) before running it. setTimeout(function () { console. log('I will run after 2 seconds'); }, 2000);


7 Answers

If your app is a .Net 4.5 application, then it's somewhat easier to use Task:

private async void start_Vid_Click(object sender, EventArgs e)
{
    if (video.State != StateFlags.Running)
    {
        viewport.Visible = true;
        video.Play();
    }

    await Task.Delay(TimeSpan.FromSeconds(30));

    viewport.Visible = false;
    viewport2.Visible = true;
    pictureBox1.Visible = true;
    start_Webc();
    video2.Play();
}
like image 110
Kamyar Nazeri Avatar answered Oct 01 '22 23:10

Kamyar Nazeri


Task.Delay is not available on .NET 4.0, but you can start task, which will just sleep for 30 seconds, and later you can continue on UI thread again:

Task.Factory.StartNew(() => Thread.Sleep(30 * 1000))
            .ContinueWith((t) =>
    {
         viewport.Visible = false;
         viewport2.Visible = true;
         pictureBox1.Visible = true;
         start_Webc(); 
         video2.Play();
    }, TaskScheduler.FromCurrentSynchronizationContext());
like image 33
Sergey Berezovskiy Avatar answered Oct 01 '22 21:10

Sergey Berezovskiy


At class level define an instance of Timer (There are a few classes like this - for a winforms app you should use System.Windows.Forms.Timer)

static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

Then in your method add lines to handle its tick and start it:

private void start_Vid_Click(object sender, EventArgs e)
{
    if (video.State != StateFlags.Running)
    {
        viewport.Visible = true;
        video.Play();
    }

    myTimer.Tick += (o,ea) => {    
        viewport.Visible = false;
        viewport2.Visible = true;
        pictureBox1.Visible = true;
        start_Webc(); 
        video2.Play();
        myTimer.Stop();
    }
    myTimer.Interval = 5000; // 5 seconds
    myTimer.Start();
}
like image 21
Jamiec Avatar answered Oct 01 '22 23:10

Jamiec


System.Threading.Tasks.Task.Delay( 60 * 1000 ).ContinueWith( (_) => StartVoid() );
like image 20
Erik Avatar answered Oct 01 '22 23:10

Erik


We can do that using Task from

System.Threading.Tasks.Task.Factory.StartNew(() =>
        {
            Thread.Sleep(5000);
            this.Invoke(new Action(() => 
                Method1()));
        });
like image 22
Mahesh Avatar answered Oct 01 '22 23:10

Mahesh


There would also be a way with reactive extensions:

Observable.Return("Delayed").Delay(TimeSpan.FromSeconds(30)).Subscribe(val => Console.WriteLine("Executing delayed"));
like image 45
LaurinSt Avatar answered Oct 01 '22 23:10

LaurinSt


case WPF..

  • WPF extension:
public static partial class WpfUtils
{
    public static void RunAfter(double seconds, Action action)
    {
        if (Application.Current.Dispatcher == null)
            return;
        var myTimer = new DispatcherTimer(
            DispatcherPriority.Normal,
            Application.Current.Dispatcher)
        {
            Interval = TimeSpan.FromSeconds(seconds)
        };
        myTimer.Tick += (_, _) =>
        {
            action?.Invoke();
            myTimer.Stop();
        };
        myTimer.Start();
    }
}
  • Usage:
WpfUtils.RunAfter(3, () =>
{
    // some code
    Console.WriteLine("Running after 3 seconds");
});

Note that this code will run on the UI thread.. on the other hand, if you go with methods from Task class, the delayed code will run on a background thread.

  • Showcase:
Task.Delay(6 * 1000).ContinueWith(_ =>
{
    // this will run in a background-thread
    var b = Thread.CurrentThread.IsBackground;
    Debug.Assert(b);
    Console.WriteLine("3");
});

var timer = new DispatcherTimer
{
    Interval = TimeSpan.FromSeconds(3)
};
timer.Tick += (_, _) =>
{
    // this will run in the UI-thread
    var b = Thread.CurrentThread.IsBackground;
    Debug.Assert(!b);
    Console.WriteLine("2");
    timer.Stop();
};
timer.Start();

Console.WriteLine("1");

// output
// 1
// 2
// 3
like image 29
Muhammad Sulaiman Avatar answered Sep 22 '22 20:09

Muhammad Sulaiman