简体   繁体   中英

wait for a series of continuous tasks to finish

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;

}

I have tried wait() and get() at the end of the second task but it didnt work out(throws an unhandled exception An invalid parameter was passed to a function that considers invalid parameters fatal. ). What i want to do is return the result only when both the tasks have finished executing.

The error occurs because you return result , which was never assigned to. A default-constructed task cannot be used.

Here, the error lets you know that you made a mistake. The task doing actual work is t , but you're not returning that.

You've also got a problem in the continuation task. Calling t.then(...) creates a new task that is dependent on t , but you're not assigning the result of that call to anything. The return value is just lost.

So even if you returned t instead of result , the client code would never know you had a continuation there.

Instead, either assign again:

t = t.then(...

Or even nicer, chain the call directly after the first task.

return create_task([=] { 
    ... 
}).then([=](task<T> result) {
    ...        
});

Note that what being returned is the result of the call to then() . That's the end of the task chain, which is probably what you meant to wait for in the client code.

Another note: normally, you can just accept the T value in the continuation rather than task<T> . Exceptions and cancellation will propagate as you'd expect.

return create_task([=] { 
    ... 
}).then([=](T result) {
    ...        
});

Now, if the first task fails or is cancelled, the continuation specified in then() won't be run. And this propagates to the client code of this method as well.

In my experience, taking task<T> as a parameter is mostly useful when you want to observe and differentiate success/failure/cancellation in detail (like printing debug messages for instance.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM