template<class T>T MainPage::addSubtract(T num1, T num2,boolean add){
T result;
task<T> t( [num1, num2, add,result]()->T{
if (num1 < 0 || num2 < 0){
throw ref new Exception(-1, "Invalid Arguments");
}
else{
if (add){
OutputDebugString(num1.ToString()->Data());
OutputDebugString(L"\n");
OutputDebugString(num2.ToString()->Data());
return num1 + num2;
}
else{
return num1 - num2;
}
}
});
t .then([result](task<T> t)mutable->T{
try{
//T result;
OutputDebugString(L"REsult= ");
result = t.get();
OutputDebugString(result.ToString()->Data());
//this->resultTextBlock->Text = result.ToString();
return result;
}
catch (Exception^ e){
OutputDebugString(L"Exception encountered");
return -1;
}
});
return result;
}
我在第二个任务结束时尝试了wait()和get(),但它没有成功(抛出未处理的异常An invalid parameter was passed to a function that considers invalid parameters fatal.
)。我想要做的是仅在两个任务都完成执行时返回结果。
答案 0 :(得分:0)
发生错误是因为您返回了从未分配过的result
。无法使用默认构造的任务。
在这里,错误让你知道你犯了一个错误。执行实际工作的任务是t
,但您没有返回。
您在延续任务中也遇到了问题。调用t.then(...)
会创建一个取决于t
的新任务,但您不会将该调用的结果分配给任何内容。返回值刚刚丢失。
因此,即使您返回t
而不是result
,客户端代码也永远不会知道您有继续。
相反,要么再次分配:
t = t.then(...
甚至更好,在第一个任务后直接链接呼叫。
return create_task([=] {
...
}).then([=](task<T> result) {
...
});
请注意,返回的内容是调用then()
的结果。这就是任务链的结束,这可能是你在客户端代码中等待的意思。
另一个注意事项:通常,您可以在延续中接受T
值,而不是task<T>
。例外和取消将按照您的预期传播。
return create_task([=] {
...
}).then([=](T result) {
...
});
现在,如果第一个任务失败或被取消,那么then()中指定的延续将不会被运行。并且这也传播到此方法的客户端代码。
根据我的经验,当您想要详细观察和区分成功/失败/取消(例如打印调试消息)时,将task<T>
作为参数非常有用。