75 lines
2.3 KiB
C++
75 lines
2.3 KiB
C++
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
#pragma once
|
|
#include <wrl/wrappers/corewrappers.h>
|
|
|
|
namespace CalculatorApp
|
|
{
|
|
class AsyncHelper
|
|
{
|
|
public:
|
|
static concurrency::task<void> RunOnUIThreadAsync(std::function<void()>&& action);
|
|
static void RunOnUIThread(std::function<void()>&& action, DWORD timeout = INFINITE);
|
|
static void Delay(DWORD milliseconds);
|
|
|
|
template <typename T>
|
|
static void RunOnUIThread(std::function<concurrency::task<T>()>&& action, DWORD timeout = INFINITE)
|
|
{
|
|
concurrency::task<T> t;
|
|
concurrency::task<void> uiTask =
|
|
RunOnUIThreadAsync([&t, action]() { t = action(); }).then([&t]() { t.wait(); }, concurrency::task_continuation_context::use_arbitrary());
|
|
|
|
WaitForTask<void>(uiTask, timeout);
|
|
}
|
|
|
|
template <typename T>
|
|
static bool WaitForTask(concurrency::task<T>& t, DWORD timeout = INFINITE)
|
|
{
|
|
Microsoft::WRL::Wrappers::Event event(CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
|
|
if (!event.IsValid())
|
|
{
|
|
throw std::bad_alloc();
|
|
}
|
|
|
|
Platform::Exception ^ ex;
|
|
t.then(
|
|
[&event, &ex](concurrency::task<T> prevTask) {
|
|
try
|
|
{
|
|
prevTask.get();
|
|
}
|
|
catch (Platform::Exception ^ e)
|
|
{
|
|
ex = e;
|
|
}
|
|
|
|
if (event.IsValid())
|
|
{
|
|
SetEvent(event.Get());
|
|
}
|
|
},
|
|
concurrency::task_continuation_context::use_arbitrary());
|
|
|
|
DWORD waitResult; // = STATUS_PENDING;
|
|
waitResult = WaitForSingleObjectEx(event.Get(), timeout, true);
|
|
event.Close();
|
|
|
|
if (ex != nullptr)
|
|
{
|
|
throw ex;
|
|
}
|
|
|
|
if (waitResult == WAIT_FAILED)
|
|
{
|
|
throw ref new Platform::Exception(-1, L"Error in waiting for task completion: " + waitResult.ToString());
|
|
}
|
|
|
|
return waitResult == WAIT_OBJECT_0;
|
|
}
|
|
|
|
private:
|
|
static void Sleep(DWORD milliseconds);
|
|
};
|
|
}
|