繁体   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;

}

我在第二个任务结束时尝试了wait()和get(),但没有成功(抛出未处理的异常) 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>作为参数非常有用。

暂无
暂无

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

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