78 lines
2.3 KiB
C++
78 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);
|
|
};
|
|
}
|