calculator/internal/CalculatorUnitTests/AsyncHelper.h
Howard Wolosky c13b8a099e Hello GitHub
2019-01-28 16:24:37 -08:00

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);
};
}