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();
}
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);
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();
}
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());
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();
}
System.Threading.Tasks.Task.Delay( 60 * 1000 ).ContinueWith( (_) => StartVoid() );
We can do that using Task from
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
this.Invoke(new Action(() =>
Method1()));
});
There would also be a way with reactive extensions:
Observable.Return("Delayed").Delay(TimeSpan.FromSeconds(30)).Subscribe(val => Console.WriteLine("Executing delayed"));
case WPF..
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();
}
}
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With