一般に、アダムの答えが言うように、ブロックではなく、継続 (.then(...)) を使用する必要があります。しかし、何らかの理由で (コードをテストするために) 待機したい場合は、最後の継続からイベントをトリガーできます (C# の用語を使用するため):
TEST_METHOD(AsyncOnThreadPoolUsingEvent)
{
std::shared_ptr<Concurrency::event> _completed = std::make_shared<Concurrency::event>();
int i;
auto workItem = ref new WorkItemHandler(
[_completed, &i](Windows::Foundation::IAsyncAction^ workItem)
{
Windows::Storage::StorageFolder^ _picturesLibrary = Windows::Storage::KnownFolders::PicturesLibrary;
Concurrency::task<Windows::Storage::StorageFile^> _getFileObjectTask(_picturesLibrary->GetFileAsync(L"art.bmp"));
auto _task2 = _getFileObjectTask.then([_completed, &i](Windows::Storage::StorageFile^ file)
{
i = 90210;
_completed->set();
});
});
auto asyncAction = ThreadPool::RunAsync(workItem);
_completed->wait();
int j = i;
}
ところで、このメソッドは、ビジュアル スタジオのテストで終了後に、何らかの理由で例外が発生します。アプリでもテストしましたが、問題なく動作しました。テストの何が問題なのかよくわかりません。
C++/Wrl の例が欲しい人がいれば、私もそれを持っています。
2017 年 7 月 8 日更新: ここで要求されたのは、C++/Wrl の例です。Visual Studio 2017 のユニバーサル Windows (10) テスト プロジェクトでこれを実行しましCallback<Implements< RuntimeClassFlags<ClassicCom >, IWorkItemHandler , FtmBase >>
たCallback<IWorkItemHandler>
。私が後者を持っていたとき、それが.exeプロジェクトにあったときを除いて、プログラムは詰まっていました. ここでこのソリューションを見つけました: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/ef6f84f6-ad4d-44f0-a107-3922d56662e6/thread-pool-task-blocking-ui-thread。詳細については、「アジャイル オブジェクト」を参照してください。
#include "pch.h"
#include "CppUnitTest.h"
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <wrl/event.h>
#include <memory>
#include "concrt.h"
#include <Windows.System.Threading.h>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace Windows::System::Threading;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::System::Threading;
namespace TestWinRtAsync10
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(AsyncOnThreadPoolUsingEvent10Wrl)
{
HRESULT hr = BasicThreadpoolTestWithAgileCallback();
Assert::AreEqual(hr, S_OK);
}
HRESULT BasicThreadpoolTestWithAgileCallback()
{
std::shared_ptr<Concurrency::event> _completed = std::make_shared<Concurrency::event>();
ComPtr<ABI::Windows::System::Threading::IThreadPoolStatics> _threadPool;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_System_Threading_ThreadPool).Get(), &_threadPool);
ComPtr<IAsyncAction> asyncAction;
hr = _threadPool->RunAsync(Callback<Implements<RuntimeClassFlags<ClassicCom>, IWorkItemHandler, FtmBase>>([&_completed](IAsyncAction* asyncAction) -> HRESULT
{
// Prints a message in debug run of this test
std::ostringstream ss;
ss << "Threadpool work item running.\n";
std::string _string = ss.str();
std::wstring stemp = std::wstring(_string.begin(), _string.end());
OutputDebugString(stemp.c_str());
//
_completed->set();
return S_OK;
}).Get(), &asyncAction);
_completed->wait();
return S_OK;
}
};
}
2017 年 8 月 8 日更新: コメントごとのその他の例。
#include "pch.h"
#include "CppUnitTest.h"
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <wrl/event.h>
#include <memory>
#include "concrt.h"
#include <Windows.System.Threading.h>
#include <Windows.ApplicationModel.Core.h>
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
namespace TestWinRtAsync10
{
TEST_CLASS(TestWinRtAsync_WrlAsyncTesting)
{
public:
TEST_METHOD(PackageClassTest)
{
ComPtr<ABI::Windows::ApplicationModel::IPackageStatics> _pPackageStatics;
HRESULT hr = GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_ApplicationModel_Package).Get(), &_pPackageStatics);
ComPtr<ABI::Windows::ApplicationModel::IPackage> _pIPackage;
hr = _pPackageStatics->get_Current(&_pIPackage);
ComPtr<ABI::Windows::ApplicationModel::IPackage3> _pIPackage3;
hr = _pIPackage->QueryInterface(__uuidof(ABI::Windows::ApplicationModel::IPackage3), &_pIPackage3);
ComPtr<__FIAsyncOperation_1___FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry> _pAsyncOperation;
hr = _pIPackage3->GetAppListEntriesAsync(&_pAsyncOperation);
std::shared_ptr<Concurrency::event> _completed = std::make_shared<Concurrency::event>();
_pAsyncOperation->put_Completed(Microsoft::WRL::Callback<Implements<RuntimeClassFlags<ClassicCom>, ABI::Windows::Foundation::IAsyncOperationCompletedHandler <__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry*>, FtmBase >>
([&_completed](ABI::Windows::Foundation::IAsyncOperation<__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry*>* pHandler, AsyncStatus status)
{
__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry* _pResults = nullptr;
HRESULT hr = pHandler->GetResults(&_pResults);
ComPtr<ABI::Windows::ApplicationModel::Core::IAppListEntry> _pIAppListEntry;
unsigned int _actual;
hr = _pResults->GetMany(0, 1, &_pIAppListEntry, &_actual);
ComPtr<ABI::Windows::ApplicationModel::IAppDisplayInfo> _pDisplayInfo;
hr = _pIAppListEntry->get_DisplayInfo(&_pDisplayInfo);
Microsoft::WRL::Wrappers::HString _HStrDisplayName;
hr = _pDisplayInfo->get_DisplayName(_HStrDisplayName.GetAddressOf());
const wchar_t * _pWchar_displayName = _HStrDisplayName.GetRawBuffer(&_actual);
OutputDebugString(_pWchar_displayName);
_completed->set();
return hr;
}).Get());
_completed->wait();
};
};
}
これは次のように出力されました:
TestWinRtAsync10