Каковы преимущества возврата задачи из функции?

Я видел, как create_task используется несколькими способами:

void Bob()
{
    create_task() { /* do stuff */ }.then([](){ /* do more stuff */ });
}

и

task<void> Bob()
{
    return create_task() { /* do stuff */ }.then([](){ /* do more stuff */ });
}

Зачем возиться с возвратом задачи (во втором примере), если асинхронного поведения можно добиться любым подходом?

Уточнение: я не спрашиваю конкретно о типе возвращаемого значения void. Это может быть int, объект или что-то еще.


person Craig    schedule 10.04.2018    source источник
comment
Непонятно, что вы спрашиваете.   -  person R Sahu    schedule 10.04.2018
comment
@R Sahu - Не знаю, как это неясно; Я спрашиваю, когда можно вернуть объект задачи, когда кажется ненужным достижение асинхронного поведения. Я переформулировал вопрос, чтобы прояснить этот момент.   -  person Craig    schedule 10.04.2018
comment
Мне непонятно, потому что нет объяснения, что такое task и как оно используется в вашем приложении.   -  person R Sahu    schedule 10.04.2018
comment
В этой статье Реализация асинхронного шаблона на основе задач содержит обсуждение, которое может оказаться полезным.   -  person Richard Chambers    schedule 10.04.2018
comment
Вы конкретно спрашиваете о случае, когда задача имеет возвращаемый тип void? Потому что очевидно, что если задача возвращает значение, вам нужен объект задачи, чтобы получить значение. Если нет, это все равно может быть полезно для проверки завершения задачи.   -  person Sean Burton    schedule 10.04.2018
comment
@RSahu, вопрос очень ясен, особенно с указанными тегами. Это немного ориентировано на мнение, однако основной вопрос заключается в том, каковы плюсы и минусы двух подходов.   -  person Richard Chambers    schedule 10.04.2018
comment
@Sean Burton - ... это все еще может быть полезно для проверки выполнения задачи - я думаю, это то, что я искал.   -  person Craig    schedule 10.04.2018
comment
@SeanBurton, может показаться, что объект Task также можно использовать для дальнейших продолжений?   -  person Richard Chambers    schedule 10.04.2018


Ответы (1)


void/task<void> здесь особый случай, потому что вы можете волшебно использовать void из ниоткуда. Вы не могли сделать то же самое с int, std::string или подобными.

void Bob()
{
    create_task() { /* do stuff */ }.then([](){ /* do more stuff */ });
}

После того, как это вернулось, /* do stuff */ и /* do more stuff */ запустились, и любой дескриптор их хода отбрасывается.

task<void> Bob()
{
    return create_task() { /* do stuff */ }.then([](){ /* do more stuff */ });
}

После того, как это вернулось, /* do stuff */ и /* do more stuff */ запустились, и у вас есть дескриптор, чтобы дождаться их завершения.

int Alice()
{
    return create_task() { /* do stuff */ }.then([](){ /* do more stuff */ return 42; }).get();
}

После того, как это вернулось, /* do stuff */ и /* do more stuff */ завершили и стали доступны окончательные результаты.

task<int> Alice()
{
    return create_task() { /* do stuff */ }.then([](){ /* do more stuff */ return 42; });
}

После того, как это вернулось, /* do stuff */ и /* do more stuff */ запустились, и у вас есть дескриптор, чтобы дождаться их завершения и получить результат.

person Caleth    schedule 10.04.2018
comment
Спасибо, Калет. Можете ли вы добавить к своему ответу пример использования дескриптора, чтобы дождаться окончания и получить результат? - person phonetagger; 10.04.2018
comment
@phonetagger примеры в Составление задач — это распространенный шаблон, когда несколько задач запускаются, а затем продолжаются, когда они будут выполнены. - person Caleth; 10.04.2018
comment