дождитесь окончания серии непрерывных заданий

0
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.). То, что я хочу сделать, это вернуть результат только тогда, когда обе задачи завершили выполнение.

Теги:
lambda
visual-c++
c++-cx

1 ответ

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> в качестве параметра в основном полезно, когда вы хотите наблюдать и отличать успех/отказ/отмену в деталях (например, печатать отладочные сообщения).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню