calculator/src/CalculatorUnitTests/AsyncHelper.h
Stephanie Anderl a418777f02
Merge master into feature/GraphingCalculator branch (#585)
* Merge master into feature/GraphingCalculator branch
2019-07-15 11:17:21 -07:00

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