jsls
jsls

Reputation: 261

How to put a delay between 2 tasks?

I would like to put a delay between 2 actions , let the others tasks (that are between the 2 actions) occurs during this delay but the code will wait until the delay is over to process the second action.

For example like this:

Stopwatch sw = new Stopwatch();

public void 
{
If (checkbox1.checked)
{
   random1.class1();    //action 1
   random2.class2();   //action 2
   sw.start();
}
If (checkbox2.checked)
{
   Random2.class1();    //action 3
   Random2.class2();   //action 4
   sw.stop();
}
 MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
}

Conditions probably takes times to be checked(can't be neglected though)

I want the most precise delay i could have between action 2 & 4 . I tried with System.Threading.Thread.Sleep(10); but it makes just stop the code for 10 ms but after it takes times to check the condition and even more to do action3. I check it with stopwatch and the delay between actions 2 & 4 is fluctuating too much.

I want to put a delay between action 2 & 4 for example 100ms, the code will first check the condition then do action 3 and wait until my delay is over and once the delay s over it ll do action 4. Like that I ll have a precise delay between my 2 methods. How could I do that?!

Upvotes: 0

Views: 1348

Answers (3)

Explisam
Explisam

Reputation: 749

You could Asynchronous your actions to start in sequence or in a particular order by adding:

using System.Threading.Tasks;

And then:

Task Action1()
{
    // do stuff
    return Task.FromResult(true)
}

Task Action2()
{
    // do more stuff
    return Task.FromResult(true)
}

async void DoInOrder()
{
    await Action1(); // waits for Action1 to finish
    await Action2(); // waits for Action2 to finish
}

Or you could use it for the actual purpose you are delaying between both, if they are directly dependent, like this :

Task<int> GetMyInt()
{
    int value = 3;
    return Task.FromResult(value);
}

async void DoWithMyInt()
{
    int SomeInt = await GetMyInt(); // will wait for GetMyInt()
                                    // to return then assign value
                                    // to SomeInt and then continue
}

Upvotes: 2

Eric Lippert
Eric Lippert

Reputation: 660004

The aptly-named Task.Delay is for inserting a delay between tasks. As you note, you want an asynchronous wait so that the thread can keep doing work, so remember to await the delay task.

Note that the delay is not very high precision. Windows is not a real-time operating system, as the other answer correctly notes.

Upvotes: 4

Gusman
Gusman

Reputation: 15151

You will never get precisse delays at the granularity you want (you're taking in acount things like the time to check the condition which presumabily will be just nanoseconds, so I assume you need a precission of nanoseconds or microseconds).

Windows is not an RTOS, so you can't ensure the exact timming for your app at these levels.

EDIT:

Acording to what you said, something near 10ms can be acceptable, depending on your computer it can be 15ms as the time resolution of windows can have these variations.

You can use something like this:

Stopwatch sw = new Stopwatch();

public void 
{
    If (checkbox1.checked)
    {
       random1.class1();    //action 1
       random2.class2();   //action 2
       sw.start();
    }

    If (checkbox2.checked)
    {
        Random2.class1();    //action 3
        var timeToSleep = (int)Math.Max(100 - sw.ElapsedMilliseconds, 0);
        Thread.Sleep(timeToSleep);
        sw.stop(); //You stop the watch here, you're measuring the time from task2 to task4, not the time which action 4 takes to execute
        Random2.class2();   //action 4

    }

    MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
}

Upvotes: 1

Related Questions