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;
}
Я попытался подождать () и получить () в конце второго задания, но это не сработало (выдает необработанное исключениеAn invalid parameter was passed to a function that considers invalid parameters fatal.
). То, что я хочу сделать, это вернуть результат только тогда, когда обе задачи закончили выполнение.
Ошибка возникает потому, что вы вернетесь 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>
как параметр в основном полезен, когда вы хотите детально наблюдать и различать успех / неудачу / отмену (например, печать отладочных сообщений).
Других решений пока нет …