create_task并返回值
create_task and return values
我需要在我声明的方法中调用Async方法。该方法应返回一个值。我正在尝试将对Windows应用商店的调用包装成一个易于使用的类。我的方法应该是这样的:
bool Purchase(enum_InAppOption optionToPurchase);
enum_InAppOption
是一个枚举,包含要购买的所有应用内选项。在某个时刻,我需要调用RequestProductPurchaseAsync
。此调用的结果确定该方法应该返回true
还是false
。我是c++/cx的新手(或者至少从现在到上次使用c++,我有很长的历史),所以也许这比我想象的更容易。
create_task
看起来像这样:
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(this->_LastProductId, false))
我考虑过/尝试过的选项:
返回任务不会抽象存储
尝试调用wait处理任务。我有异常
An invalid parameter was passed to a function that considers invalid parameters fatal.
尝试使用
structured_task_group
,但这似乎不允许使用非void返回方法,或者我试图提供错误的解释。编译器返回错误C2064(已在谷歌上搜索,但我不知道该更改什么)使用任务阵列和
when_all
在上找到以下代码http://msdn.microsoft.com/en-us/library/dd492427.aspx#when_all在页面中间:
array<task<void>, 3> tasks =
{
create_task([] { wcout << L"Hello from taskA." << endl; }),
create_task([] { wcout << L"Hello from taskB." << endl; }),
create_task([] { wcout << L"Hello from taskC." << endl; })
};
auto joinTask = when_all(begin(tasks), end(tasks));
// Print a message from the joining thread.
wcout << L"Hello from the joining thread." << endl;
// Wait for the tasks to finish.
joinTask.wait();
所以我试着把它翻译成以下代码:
array<task<Platform::String^>,1> tasks = {
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(this->_LastProductId, false))
};
尽管我包含了编译器抛出C2065("array":未声明的标识符)、C2275("concurrent::task<_ReturnType>':非法使用此类型作为表达式,以及一些似乎是这两个之后的错误的错误。
综上所述:如何在异步任务完成后让方法返回,这样我就可以根据异步进行的事情返回一个有意义的结果?
如何在异步任务完成后让方法返回,这样我就可以根据异步进行的事情返回有意义的结果?
这没有多大意义:如果你想在返回之前等待它完成,那么"东西"就不是异步的。这就是同步的定义。
使用C++/CX时,不能在STA上等待尚未完成的任务。任何这样做的尝试都将导致抛出异常。如果要在STA上调用Purchase()
,并且它启动了异步操作,则不能等待该操作完成后再返回。
相反,当异步操作完成时,可以使用.then
执行另一个操作。如果需要在调用线程上执行延续,请确保传递use_current()
延续上下文,以确保在正确的上下文中执行延续。
Sascha,
- 返回一个任务将抽象出存储,我认为这将是最合理的决定,因为你没有限制助手类的用户直接获得结果,而是允许他们以自己的方式异步处理结果
-
正如@James正确提到的,你不允许在UI线程中等待,然后你会让应用程序没有响应,有不同的方法可以避免等待:
- 使用
concurrency::task::then
创建一个延续 -
你不能在UI线程中等待,但你可以等待UI线程上的操作完成,这意味着你可以将UI上运行的任务的未来结果包装在task_completion_event中,然后在另一个(后台)线程中等待事件并处理结果;
concurrency::task_completion_event<Platform::String^> purchaseCompleted; create_task(CurrentAppSimulator::RequestProductPurchaseAsync( this->_LastProductId, false)).then( [purchaseCompleted](concurrency::task<Platform::String^> task) { try { purchaseCompleted.set(task.get()); } catch(Platform::Exception^ exception) { purchaseCompleted.set_exception(exception); } }); // and somewhere on non-UI thread you can do Platform::String^ purchaseResult = create_task(purchaseCompleted).get();
-
您可以使用更多特定于WinRT的工具,而不是并发运行时,更准确地说,
IAsyncOperation<T>
::Completed
和IAsyncOperation<T>::GetResults
来实现前面的技巧;
- 使用
-
和
- 在这里似乎无关紧要,因为你只有一个真正的任务,那就是购买
- 从python中调用C++函数并获取返回值
- 为什么模板类中的对象不能返回值
- 返回值优化:显式移动还是隐式
- lock_guard是否保护返回值
- 调用CreateProcess()并获取字符串的返回值
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 查找 GCD:并非所有控制路径都返回值
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 如何从 std::thread 返回值
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- 方法错误"not all control paths return a value"和方法不返回值
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 对fread的返回值感到困惑
- 程序不向函数返回值
- 如何在另一个函数中使用返回值作为参数?
- 如何使用 uint64_t 键类型从 std::map<int, std::string> 返回值?
- 使用 std::p air 进行返回值优化
- 如何将C std ::未来返回值调整到C#System.Threading.tasks.task