简体   繁体   English

等待一系列连续任务完成

[英]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. ). 我在第二个任务结束时尝试了wait()和get(),但没有成功(抛出未处理的异常) 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. 发生错误是因为您返回了result ,但从未分配给它。 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. 完成实际工作的任务是t ,但您没有返回该值。

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. 调用t.then(...)创建一个依赖于t的新任务,但您并未将该调用的结果分配给任何对象。 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. 因此,即使您返回t而不是result ,客户端代码也永远不会知道您在那里有一个延续。

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() . 请注意,返回的内容是对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> . 另一个注意事项:通常,您只可以接受延续中的T值,而不是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. 现在,如果第一个任务失败或被取消,那么then()中指定的继续将不会运行。 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.) 以我的经验,当您想详细观察和区分成功/失败/取消(例如打印调试消息)时,将task<T>作为参数非常有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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