I am trying to delay my method by using a timer:
private System.Timers.Timer _delayTimer;
private void delay()
{
_delayTimer = new System.Timers.Timer();
_delayTimer.Interval = 5000;
//_delayTimer.Enabled = true;
_delayTimer.Elapsed += _delayTimer_Elapsed;
_delayTimer.Start();
someMethod();
}
}
private void _delayTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// delay for 5 seconds
}
When i am get into delay() method i want to start the timer, than i want the 5 seconds delay and only after that i want to execute someMethod() and currently this not happen, after execute delay() the someMethod() executed without 5 seconds delay
Your current code sets up the timer and then immediately executes someMethod. Instead of this, you need to put the actual method call inside your Elapsed handler:
private void delay()
{
_delayTimer = new System.Timers.Timer();
_delayTimer.Interval = 5000;
//_delayTimer.Enabled = true;
_delayTimer.Elapsed += _delayTimer_Elapsed;
_delayTimer.Start();
}
}
private void _delayTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
someMethod();
}
And if there's nothing else you intend to do you can simply write this inline:
_delayTimer = new System.Timers.Timer();
_delayTimer.Interval = 5000;
_delayTimer.Elapsed += (o, e) => someMethod();
_delayTimer.Start();
If you're in .Net4.5(or using BCL.Async pack) you can use Task.Delay
private async void delay()
{
await Task.Delay(5000);
someMethod();
}
If you're under .Net4.5
Try the below code. I'll suggest you to use System.Threading.Timer
var timer = new System.Threading.Timer(x => someMethod(), null, 5000, System.Threading.Timeout.Infinite);\
Don't forget when you use Threading.Timer someMethod will be invoked in ThreadPool thread, If you're accessing UI you need to marshal the call to UI thread.
If you want the current thread to pause for five seconds, then call Thread.Sleep. For example:
Thread.Sleep(TimeSpan.FromSeconds(5));
DoSomething();
Use a timer if you want something to happen five seconds from now, while you're doing something else. When the timer elapses, the action will be executed on a thread pool thread.
Also, if you only want the timer to execute one time (rather than once every five seconds), be sure to set AutoReset to false.
You need to call someMethod in the timer's Elapsed handler:
private void delay()
{
_delayTimer = new System.Timers.Timer();
_delayTimer.Interval = 5000;
_delayTimer.AutoReset = false; //so that it only calls the method once
_delayTimer.Elapsed += (s,args) => someMethod();
_delayTimer.Start();
}
You could also use Task.Delay instead:
private void delay()
{
Task.Delay(5000)
.ContinueWith(t => someMethod());
}
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(5000);
/*
* Here Yopur code to do some method :D
* */
});
Related
I'm trying to improve some code and want a more generic implementation of creating timers that run async. In the situation below MethodA is working as expected and writes to console every 4 seconds. I'd expect MethodB to work too, but somehow it only executes one time.
public async Task InitTimers()
{
MethodA(TimeSpan.FromSeconds(4));
MethodB(TimeSpan.FromSeconds(4), ExecTimer());
}
private async Task MethodA(TimeSpan refreshTime)
{
var aTimer = new Timer();
aTimer.Elapsed += (s, e) => ExecTimer().ConfigureAwait(false);
aTimer.Interval = refreshTime.TotalMilliseconds;
aTimer.Enabled = true;
// Immediately trigger first time
ExecTimer().ConfigureAwait(false);
}
private async Task MethodB(TimeSpan refreshTime, Task task)
{
var aTimer = new Timer();
aTimer.Elapsed += (s, e) => task.ConfigureAwait(false);
aTimer.Interval = refreshTime.TotalMilliseconds;
aTimer.Enabled = true;
// Immediately trigger first time
task.ConfigureAwait(false);
}
private async Task ExecTimer()
{
Console.WriteLine("Hello World!");
}
Any idea what causes MethodB to only run once?
Your Timers are getting disposed when they fall out of scope once the methods MethodA/MethodB complete. You'd need to create them outside the Tasks or otherwise keep the Task running and the Timer in scope
I am making a small game with an auto play feature, but the program runs too fast so the user can't see the outcome at each stage. I am using VS 2017, so I can't use async (at least from what I have read). How can I have the program wait and allow the UI to update?
I am working in a do while loop. The main chunk of the game executes, updates the UI, and then waits for the player to click a button (assuming auto play is not running), with auto play running the do while loop repeats, but after the UI updates it would wait X seconds.
Use a Timer component instead of a loop, and put the loop body in the timer's Elapsed event.
And VS2017 definitely supports async, but it wouldn't help in this case... things would still move too fast for the user.
You can use async/await to slow down the execution of event handler without having to split the logic. This is pretty simple:
async void Button_Click(object sender, RoutedEventArgs e) // wpf event handler
{
...
await Task.Delay(1000); // pause 1 second
...
while (someCondition)
{
...
await Task.Delay(1000);
...
}
}
You can read about async/await at msdn.
If you are using WPF, then you have to look into animations. They are much simpler to use to ensure smooth changes than manually changing something (position, sizes).
Usage: DelayFactory.DelayAction(500, new Action(() => { this.RunAction(); }));`
//Note Forms.Timer and Timer() have similar implementations.
//Assumes you will have a DelayFactory Static Class
public static void DelayAction(int millisecond, Action action)
{
var timer = new DispatcherTimer();
timer.Tick += delegate
{
action.Invoke();
timer.Stop();
};
timer.Interval = TimeSpan.FromMilliseconds(millisecond);
timer.Start();
}
Wait function using timers, no UI locks.
public void wait(int milliseconds)
{
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
if (milliseconds == 0 || milliseconds < 0) return;
//Console.WriteLine("start wait timer");
timer1.Interval = milliseconds;
timer1.Enabled = true;
timer1.Start();
timer1.Tick += (s, e) =>
{
timer1.Enabled = false;
timer1.Stop();
//Console.WriteLine("stop wait timer");
};
while (timer1.Enabled)
{
Application.DoEvents();
}
}
Usage:
wait(1000); //wait one second
It looks like you have a couple of options
1.You can try Sleep -(but it may hang the UI)
int Seconds = 1;
Threading.Thread.Sleep(Seconds * 1000);
2.You can try this code:
int Seconds = 1;
Private void WaitNSeconds(int seconds)
{
if (seconds < 1) return;
DateTime _desired = DateTime.Now.AddSeconds(seconds);
while (DateTime.Now < _desired) {
System.Windows.Forms.Application.DoEvents();
}
}
3.Try to use Async and see what happens
async Task MakeDelay() {
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e) {
await MakeDelay();
}
In my application I need a background thread that contacts a server every N seconds...
I made it in this way:
Task.Factory.StartNew (() => {
while(true)
{
Thread.Sleep (10000);
...do my stuff...
}
});
This solution works fine but I need to know if there is a better one. (for example: is Task.Delay(10000) a better solution?)
Thanks a lot!
If you need to use the UI you could use the example of DaveDev, otherwise the example below would also work. If you want to use UI in this example you have to use the Invoke or BeginInvoke methods of the controls.
using System;
using System.Threading;
class TimerExample
{
static void Main()
{
// Create a timer that signals the delegate to invoke
// CheckStatus after one second, and every 1/4 second
// thereafter.
Timer stateTimer = new Timer(CheckStatus);
// Change the period to every 1/2 second.
stateTimer.Change(0, 500);
}
public static void CheckStatus(Object stateInfo) {
...
}
}
I think it is important to know why not to use Thread.Sleep in this case. If you use sleep it locks up the thread. If you use a timer then the thread can be used to do other tasks in the meantime.
_timer = new DispatcherTimer();
_timer.Tick += timer_Tick;
_timer.Interval = new TimeSpan(0, 0, 0, 1);
_timer.Start();
private void timer_Tick(object sender, EventArgs e)
{
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += (s, a) =>
{
//do your stuff
};
backgroundWorker.RunWorkerAsync();
}
I am looking for an alternative to calling Thread.Sleep which does not block the thread but instead returns the thread back into the thread pool. Does such a thing exist?
Use Task.Delay
await Task.Delay(delay);
If the thread is returning to the pool, then it isn't going to do any more work in the method in question. Make the next bit of the method a separate method, and create a Timer that calls it.
You can use also a Timer for example:
using System.Timers;
private void Main()
{
Timer t = new Timer();
t.Interval = 5000; // 5 seconds
t.AutoReset = false;
t.Elapsed += new SleepDone(TimerElapsed);
t.Start();
}
private void SleepDone(object sender, ElapsedEventArgs e)
{
Console.WriteLine("HERE WHAT COME AFTER SLEEP");
}
I'm currently making a text based game, but I need the calls to pause for a certain number of milliseconds. I'm looking for something like this:
void InitProgram()
{
WriteToText("Welcome!");
CreatePause(3000); // Pause execution HERE for 3 seconds without locking UI
WriteToText("How are you?"); // Continue
StartTutorial();
}
So like, the method will be called, do its waiting thing, and then return. And when it returns, normal execution is continued.
What can I do for this effect?
You could use a timer:
readonly Timer _timer = new Timer();
void InitProgram()
{
WriteToText("Welcome!");
_timer.Interval = 3000;
_timer.Tick += timer_Tick;
_timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
WriteToText("How are you?"); // Continue
StartTutorial();
_timer.Stop();
}
If you wanted to call this multiple times, just put _timer.Start into it's own method, every time you call it, 3 seconds later whatever is in timer_Tick will happen:
private void StartTimer()
{
_timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
WriteToText("How are you?"); // Continue
StartTutorial();
_timer.Stop();
}
If target framework is 4.0 or higher and IDE is VS2012 or higher, then you can use async/await
private async void Foo()
{
Console.WriteLine("Going to Await");
await Task.Delay(5000);
Console.WriteLine("Done with awaiting");
}
It's pretty simple and straightforward and the biggest advantage is, that your "linear" flow is kept, because the necessary callbacks etc are handled by the compiler automatically.
How about something like this?
Its all pseudo code, I have not tested...
Thread _thread;
void InitProgram()
{
WriteToText("Welcome!");
ThreadStart ts = new ThreadStart(StartThread);
_thread = new Thread(ts);
_thread.Start();
}
private void StartThread()
{
Thread.CurrentThread.Sleep(3000);
this.Invoke(delegate { this.StartTutorial(); });
}
private void StartTutorial()
{
WriteToText("How are you?"); // Continue
//Start tutorial
}
Hahahahhaha! I figured out the answer using possibly the most crazy method available! Check this out, guys!
First, declare global List:
private List<Action> actionList = new List<Action>();
Now, this is what you do in the method you wish to call wait from:
WriteToLog("Hello!");
Action act = delegate() { WriteToLog("How are you?"); }; actionList.Add(act); // Create a new Action out of this method and add it to the action list!
CreatePause(3000); // Call the method with your specified time
void CreatePause(int millisecondsToPause)
{
Action w = delegate() { Thread.Sleep(millisecondsToPause); };
for (int i = 0; i < actionList.Count; i++) // Iterate through each method in the action list that requires attention
{
Action a_Instance = (Action)actionList[i]; // Add a cast to each iteration
AsyncCallback cb = delegate(IAsyncResult ar) { Invoke(a_Instance); w.EndInvoke(ar); }; // Do each method!!!!
w.BeginInvoke(cb, null);
}
actionList.Clear(); // Clear that list!
return; // Return!
}
To be honest, this shouldn't work, but it does.