C++ equivalent of .NET's Task.Delay?
Asked Answered
M

4

7

I'm writing a C++/CX component to be consumed by Window's store Apps. I'm looking for a way to accomplish what Task.Delay(1000) does in C#.

Meanly answered 10/12, 2012 at 18:19 Comment(0)
M
3

Old Question, but still unanswered.

You can use

#include <chrono>
#include <thread>


std::this_thread::sleep_for(std::chrono::milliseconds(1000));

This will need C++11, which shouldn't be a problem when using C++/CX.

Mahaffey answered 15/8, 2013 at 6:45 Comment(1)
Sleeping and getting scheduled later is not really the same thing however.Manda
W
2

After one year of using C++/CX, I have a general and reasonably correct answer to this question.

This link (from the Visual C++ Parallel Patterns Library documentation) includes a snippet for a function called complete_after(). That function creates a task that will complete after the specified number of milliseconds. You can then define a continuation task that will execute afterwards:

void MyFunction()
{
    // ... Do a first thing ...

    concurrency::create_task(complete_after(1000), concurrency::task_continuation_context::use_current)
    .then([]() {
        // Do the next thing, on the same thread.
    });
}

Or better yet, if you use Visual C++'s coroutines capabilities simply type:

concurrency::task<void> MyFunctionAsync()
{
    // ... Do a first thing ...

    co_await complete_after(1000);
    // Do the next thing.
    // Warning: if not on the UI thread (e.g., on a threadpool thread), this may resume on a different thread.
}
Warren answered 9/1, 2018 at 18:44 Comment(4)
The coroutines code gives me: "this co_await expression requires a suitable "await_ready" function and none was found" :/Aarika
Felix - for coroutines to work, the calling function needs to have a concurrency::task<void> return type. If the calling function has void return type, you get that message.Warren
I now see that there's even a concurrency::wait(ms) function, that could be used for a simpler implementation of complete_after(). learn.microsoft.com/en-us/cpp/parallel/concrt/reference/…Warren
Huh, I thought I'd changed the return type to concurrency::task<void> :/ Ooh, concurrency::wait(ms) looks promising :)Aarika
P
0

You could create a concurrency::task, wait for 1000 time units and then call the ".then" method for the task. This will ensure that there is at least a wait of 1000 time units between the time you created the task and between the time it gets executed.

Personally answered 16/12, 2012 at 10:57 Comment(3)
That's a cyclical question, once in the task, how do you wait??Voile
::WaitForSingleObjectEx(::GetCurrentThread(), milliseconds, FALSE);Wrongful
Luc Bloom's solution is fine. I hadn't realized that Win32 API was still permitted for UWP apps, but it is.Warren
W
0

I'm not going to claim to be a wizard - I'm still fairly new to UWP and C++/CX., but what I'm using is the following:

public ref class MyClass sealed {
public:
    MyClass()
    {
        m_timer = ref new Windows::UI::Xaml::DispatcherTimer;
        m_timer->Tick += ref new Windows::Foundation::EventHandler<Platform::Object^>(this, &MyClass::PostDelay);
    }
    void StartDelay()
    {
        m_timer->Interval.Duration = 200 * 10000;// 200ms expressed in 100s of nanoseconds
        m_timer->Start();
    }
    void PostDelay(Platform::Object^ sender, Platform::Object ^args)
    {
        m_timer->Stop();
        // Do some stuff after the delay
    }
private:
    Windows::UI::Xaml::DispatcherTimer ^m_timer;
}

The main advantage over other approaches is that:

  1. it's non-blocking
  2. You're guaranteed to be called back on the XAML UI thread
Warren answered 23/12, 2016 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.