It's clear: For example, imagine a button in my form. When a user clicks on the button, some void method should run after 30 seconds.
There would be a void method DoAfterDelay
that takes two input parameter. The first one is the method to do (using delegates), and the other one is the time interval. So I'll have:
public delegate void IVoidDelegate();
static void DoAfterDelay(IVoidDelegate TheMethod, TimeSpan Interval)
{
// *** Some code that will pause the process for "Interval".
TheMethod();
}
So, I just need a piece of code to pause the process for a specific time interval. Heretofore, I used this code to do that:
System.Threading.Thread.Sleep(Interval);
But this code is no good for me, because it stops the whole process and freezes the program. I don't want the program to get stuck in the DoAfterDelay
method. That's why the Thread.Sleep
is useless.
So could anyone suggest a better way? Of course I've searched about that, but most of the solutions I've found were based on using a timer (like here for example). But using a timer is my last opinion, because the method should run once and using timers makes the program confusing to read. So I'm looking for a better solution if there is. Or maybe I have to use timers?
I guess I have to play with threads, but not sure. So I wonder if anyone could guide me to a solution. Thanks in advance.
Can you use a task?
Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(Interval);
TheMethod();
});
This is where you can use the async await functionality of .Net 4.5
You can use Task.Delay an give the delay in miliseconds.
This is a very clean way. ex:
private async void button1_Click(object sender, EventArgs e)
{
await Task.Delay(5000);
TheMethod();
}
DoAfterDelay starts a timer that just runs once, that when it expires it calls your void 'TheMethod'function.
Why would this be messy?
Here's what you want:
public static void Example1c()
{
Action action = DoSomethingCool;
TimeSpan span = new TimeSpan(0, 0, 0, 5);
ThreadStart start = delegate { RunAfterTimespan(action, span); };
Thread t4 = new Thread(start);
t4.Start();
MessageBox.Show("Thread has been launched");
}
public static void RunAfterTimespan(Action action, TimeSpan span)
{
Thread.Sleep(span);
action();
}
private static void DoSomethingCool()
{
MessageBox.Show("I'm doing something cool");
}
One of the benefits of using Action is that it can be easily modified to pass in parameters. Say you want to be able to pass an integer to DoSomethingCool. Just modify thusly:
public static void Example1c()
{
Action<int> action = DoSomethingCool;
TimeSpan span = new TimeSpan(0, 0, 0, 5);
int number = 10;
ThreadStart start = delegate { RunAfterTimespan(action, span, number); };
Thread t4 = new Thread(start);
t4.Start();
MessageBox.Show("Thread has been launched");
}
public static void RunAfterTimespan(Action<int> action, TimeSpan span, int number)
{
Thread.Sleep(span);
action(number);
}
private static void DoSomethingCool(int number)
{
MessageBox.Show("I'm doing something cool");
}
Very flexible...
There are several methods of creating thread but of course, it depends on what you are doing.
You can create a thread on the fly like this:
Thread aNewThread = new Thread(
() => OnGoingFunction()
);
aNewThread.Start();
This thread will be running in the background. The function you want to do should have a sleep method to sleep when its done processing. So something like this:
private void OnGoingFunction()
{
//Code....
Thread.Sleep(100); //100 ms, this is in the thead so it will not stop your winForm
//More code....
}
I hope that helps.
Another option is to create the thread whenever you need to process it and not worry about the sleep option. Just create a new thread every time to load the process
You should create a Coroutine
public IEnumerator waitAndRun()
{
// WAIT FOR 3 SEC
yield return new WaitForSeconds(3);
// RUN YOUR CODE HERE ...
}
And call it with:
StartCoroutine(waitAndRun());
You can specify the exact seconds by using
DateTime runTime = new DateTime();
double waitSeconds = (runTime - DateTime.Now).TotalSeconds;
Task.Factory.StartNew(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(waitSeconds));
YourMethod();
});
runTime => When you want to execute the method.