Зачем нужен ContinueWith, если в {} можно поместить обе задачи
От: Passerby  
Дата: 27.12.19 12:14
Оценка:
В руководстве https://metanit.com/sharp/tutorial/12.3.php приводится пример использования ContinueWith:
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
 
namespace HelloApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Task<int> task1 = new Task<int>(()=>Sum(4,5));
 
            // задача продолжения
            Task task2 = task1.ContinueWith(sum => Display(sum.Result));
 
            task1.Start();
 
            // ждем окончания второй задачи
            task2.Wait();
            Console.WriteLine("End of Main");
            Console.ReadLine();
        }
 
        static int Sum(int a, int b) => a + b;
        static void Display(int sum)
        {
            Console.WriteLine($"Sum: {sum}");
        }
 
    }
}

Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task?
Task task1 = new Task(() => { int sum = Sum(4, 5); Display(sum); });
            task1.Start();
            task1.Wait();
            Console.WriteLine("End of Main");
            Console.ReadLine();

В каких случаях так нельзя сделать и нужно применять ContinueWith?
Re: ContinueWith
От: Qbit86 Кипр
Дата: 27.12.19 12:20
Оценка: +2
Здравствуйте, Passerby, Вы писали:

P>Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task?

P>В каких случаях так нельзя сделать и нужно применять ContinueWith?

Например, в тех случаях, когда таску тебе возвращает другой метод, а не ты её конструируешь из делегата.
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: ContinueWith
От: Passerby  
Дата: 27.12.19 12:51
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, Passerby, Вы писали:


P>>Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task?

P>>В каких случаях так нельзя сделать и нужно применять ContinueWith?

Q>Например, в тех случаях, когда таску тебе возвращает другой метод, а не ты её конструируешь из делегата.

Не понял. В смысле если первый метод возвращает делегат? В чем отличие? Не мог бы пару строк: первый метод и метод, помещенный в ContinueWith, а то не соображу, что имеешь в виду?
Re[3]: ContinueWith
От: Qbit86 Кипр
Дата: 27.12.19 13:10
Оценка: 2 (1)
Здравствуйте, Passerby, Вы писали:

P>Не мог бы пару строк: первый метод и метод, помещенный в ContinueWith, а то не соображу, что имеешь в виду?


using System;
using System.Threading.Tasks;
using ThirdPartyLibrary;

namespace ThirdPartyLibrary
{
    public static class ClosedSourceClass
    {
        public static Task<int> ClosedSourceMethod() => Task.Run(() => Sum(4, 5));

        private static int Sum(int a, int b) => a + b;
    }
}

namespace HelloApp
{
    internal static class Program
    {
        private static void Main()
        {
            Task<int> task1 = ClosedSourceClass.ClosedSourceMethod();

            // задача продолжения
            Task task2 = task1.ContinueWith(sum => Display(sum.Result), TaskScheduler.Default);

            // ждем окончания второй задачи
            task2.Wait();
            Console.WriteLine("End of Main");
            Console.ReadLine();
        }

        private static void Display(int sum)
        {
            Console.WriteLine($"Sum: {sum}");
        }
    }
}
Глаза у меня добрые, но рубашка — смирительная!
Re[4]: ContinueWith
От: Sharov Россия  
Дата: 27.12.19 13:28
Оценка: +1
Здравствуйте, Qbit86, Вы писали:


Пидантизьму ради Async бы добавить в название метода ClosedSourceMethod.
Кодом людям нужно помогать!
Re[4]: ContinueWith
От: Passerby  
Дата: 27.12.19 13:28
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, Passerby, Вы писали:


P>>Не мог бы пару строк: первый метод и метод, помещенный в ContinueWith, а то не соображу, что имеешь в виду?


Q>
Q>using System;
Q>using System.Threading.Tasks;
Q>using ThirdPartyLibrary;

Q>namespace ThirdPartyLibrary
Q>{
Q>    public static class ClosedSourceClass
Q>    {
Q>        public static Task<int> ClosedSourceMethod() => Task.Run(() => Sum(4, 5));

Q>        private static int Sum(int a, int b) => a + b;
Q>    }
Q>}

Q>namespace HelloApp
Q>{
Q>    internal static class Program
Q>    {
Q>        private static void Main()
Q>        {
Q>            Task<int> task1 = ClosedSourceClass.ClosedSourceMethod();

Q>            // задача продолжения
Q>            Task task2 = task1.ContinueWith(sum => Display(sum.Result), TaskScheduler.Default);

Q>            // ждем окончания второй задачи
Q>            task2.Wait();
Q>            Console.WriteLine("End of Main");
Q>            Console.ReadLine();
Q>        }

Q>        private static void Display(int sum)
Q>        {
Q>            Console.WriteLine($"Sum: {sum}");
Q>        }
Q>    }
Q>}
Q>

А в чем смысл создания метода, возвращающего Task<int>? Здесь проще создать метод, возвращающий int и далее последовательное их выполнение в Task. Т.е. когда такая схема может быть полезна?
Re[5]: ContinueWith
От: Qbit86 Кипр
Дата: 27.12.19 13:39
Оценка: 2 (1) +1
Здравствуйте, Passerby, Вы писали:

P>А в чем смысл создания метода, возвращающего Task<int>? Здесь проще создать метод, возвращающий int и далее последовательное их выполнение в Task. Т.е. когда такая схема может быть полезна?


Здесь проще, потому что я твой простой код взял для примера. В общем случае у тебя может быть произвольная операция, например, I/O bound. Скажем, чтение 1000000 чисел из файла и их сложение, или скачивание из сети, etc. Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.
Глаза у меня добрые, но рубашка — смирительная!
Re[6]: ContinueWith
От: Passerby  
Дата: 27.12.19 14:40
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, Passerby, Вы писали:


P>>А в чем смысл создания метода, возвращающего Task<int>? Здесь проще создать метод, возвращающий int и далее последовательное их выполнение в Task. Т.е. когда такая схема может быть полезна?


Q>Здесь проще, потому что я твой простой код взял для примера. В общем случае у тебя может быть произвольная операция, например, I/O bound. Скажем, чтение 1000000 чисел из файла и их сложение, или скачивание из сети, etc. Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.

Понятно. Спасибо.
Re[5]: ContinueWith
От: TK Лес кывт.рф
Дата: 29.12.19 07:56
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Пидантизьму ради Async бы добавить в название метода ClosedSourceMethod.


А по возвращаемому значению разве не понятно, что метод может выполняться синхронно?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: ContinueWith
От: Sharov Россия  
Дата: 29.12.19 09:52
Оценка:
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, Sharov, Вы писали:


S>>Пидантизьму ради Async бы добавить в название метода ClosedSourceMethod.


TK>А по возвращаемому значению разве не понятно, что метод может выполняться синхронно?


Причем здесь это? Можно и не добавлять, но методы, которые возвращают task'и обычно имеют суффикс async.
Кодом людям нужно помогать!
Re[7]: Async
От: Qbit86 Кипр
Дата: 29.12.19 10:08
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Причем здесь это? Можно и не добавлять, но методы, которые возвращают task'и обычно имеют суффикс async.


Всё верно: «Asynchronous methods in TAP include the Async suffix after the operation name for methods that return awaitable types» — task-based-asynchronous-pattern-tap#naming-parameters-and-return-types
Глаза у меня добрые, но рубашка — смирительная!
Re: Зачем нужен ContinueWith, если в {} можно поместить обе задачи
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 30.12.19 09:29
Оценка: 1 (1)
Здравствуйте, Passerby, Вы писали:
Иногда нужно делать универсальный класс для оповещения из натива при подписке на события.
https://infostart.ru/public/466052/


 public class ДляВыполненияЗадачи<TResult>
        {

  static public void Выполнить(System.Threading.Tasks.Task<TResult> Задача, АсинхронныйВыполнитель выполнитель, object ДанныеКЗадаче)
        {
            Задача.ContinueWith(t => {
                  выполнитель.Оповестить(t,ДанныеКЗадаче);
            });

        }
}
и солнце б утром не вставало, когда бы не было меня
Re: Зачем нужен ContinueWith, если в {} можно поместить обе задачи
От: fmiracle  
Дата: 30.12.19 10:00
Оценка:
Здравствуйте, Passerby, Вы писали:

P>В каких случаях так нельзя сделать и нужно применять ContinueWith?


ContinueWith используется компилятором при обработке await. Соответственно, всегда когда у тебя в коде есть await, ты можешь сделать аналогичное поведение через ContinueWith. Обычно это менее удобно и потому смысла нет, но иногда может быть весьма актуально, например, если надо программно собрать последовательность асинхронных операций.
Re[2]: Зачем нужен ContinueWith, если в {} можно поместить обе задачи
От: Ночной Смотрящий Россия  
Дата: 30.12.19 21:31
Оценка:
Здравствуйте, fmiracle, Вы писали:

F>ContinueWith используется компилятором при обработке await.


На практике все несколько сложнее.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: ContinueWith
От: TK Лес кывт.рф
Дата: 14.01.20 21:38
Оценка:
Здравствуйте, Sharov, Вы писали:

S>>>Пидантизьму ради Async бы добавить в название метода ClosedSourceMethod.


TK>>А по возвращаемому значению разве не понятно, что метод может выполняться синхронно?

S>Причем здесь это? Можно и не добавлять, но методы, которые возвращают task'и обычно имеют суффикс async.

Это карго-культ, а не педантизм.

ps
про Task.XXX забыл.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: Зачем нужен ContinueWith, если в {} можно поместить обе задачи
От: TK Лес кывт.рф
Дата: 14.01.20 21:44
Оценка:
Здравствуйте, Passerby, Вы писали:

P>Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task?

P>В каких случаях так нельзя сделать и нужно применять ContinueWith?

Очевидно, что ContinueWith будет полезен во всех остальных случаях, когда обе задачи нельзя поместить в один Task
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: ContinueWith
От: TK Лес кывт.рф
Дата: 14.01.20 22:25
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Здесь проще, потому что я твой простой код взял для примера. В общем случае у тебя может быть произвольная операция, например, I/O bound. Скажем, чтение 1000000 чисел из файла и их сложение, или скачивание из сети, etc. Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.


синхронного, но завёрнутого в поток — это вообще что? и можно ли вообще читать файлы (или качать из сети) вообще без заворачиваний и потоков?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[8]: ContinueWith
От: Sharov Россия  
Дата: 14.01.20 22:46
Оценка:
Здравствуйте, TK, Вы писали:


S>>Причем здесь это? Можно и не добавлять, но методы, которые возвращают task'и обычно имеют суффикс async.

TK>Это карго-культ, а не педантизм.
TK>ps
TK>про Task.XXX забыл.

https://en.wikipedia.org/wiki/Convention_over_configuration
Кодом людям нужно помогать!
Re[7]: ContinueWith
От: Qbit86 Кипр
Дата: 15.01.20 06:58
Оценка: +1
Здравствуйте, TK, Вы писали:

Q>>Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.

TK>синхронного, но завёрнутого в поток — это вообще что?

Task<string> t = File.ReadAllTextAsync("...");

vs.
Task<string> t = Task.Run(() => File.ReadAllText("..."));
Глаза у меня добрые, но рубашка — смирительная!
Re[8]: ContinueWith
От: TK Лес кывт.рф
Дата: 15.01.20 15:00
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>>>Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.

TK>>синхронного, но завёрнутого в поток — это вообще что?

Q>
Task<string> t = File.ReadAllTextAsync("...");

Q>vs.
Q>
Task<string> t = Task.Run(() => File.ReadAllText("..."));


можно добавить еще
Task<string> t = Task.FromResult(File.ReadAllText("..."));


Это детали реализации — для потребителя данные методы должны быть равнозначны.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.