Здравствуйте, Passerby, Вы писали:
P>А в чем смысл создания метода, возвращающего Task<int>? Здесь проще создать метод, возвращающий int и далее последовательное их выполнение в Task. Т.е. когда такая схема может быть полезна?
Здесь проще, потому что я твой простой код взял для примера. В общем случае у тебя может быть произвольная операция, например, I/O bound. Скажем, чтение 1000000 чисел из файла и их сложение, или скачивание из сети, etc. Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.
Здравствуйте, Passerby, Вы писали:
P>Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task? P>В каких случаях так нельзя сделать и нужно применять ContinueWith?
Например, в тех случаях, когда таску тебе возвращает другой метод, а не ты её конструируешь из делегата.
Здравствуйте, 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: Зачем нужен ContinueWith, если в {} можно поместить обе задачи
Здравствуйте, Passerby, Вы писали:
Иногда нужно делать универсальный класс для оповещения из натива при подписке на события. https://infostart.ru/public/466052/
public class ДляВыполненияЗадачи<TResult>
{
static public void Выполнить(System.Threading.Tasks.Task<TResult> Задача, АсинхронныйВыполнитель выполнитель, object ДанныеКЗадаче)
{
Задача.ContinueWith(t => {
выполнитель.Оповестить(t,ДанныеКЗадаче);
});
}
}
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, TK, Вы писали:
Q>>Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже. TK>синхронного, но завёрнутого в поток — это вообще что?
Task<string> t = File.ReadAllTextAsync("...");
vs.
Task<string> t = Task.Run(() => File.ReadAllText("..."));
Глаза у меня добрые, но рубашка — смирительная!
Зачем нужен 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?
Здравствуйте, Qbit86, Вы писали:
Q>Здравствуйте, Passerby, Вы писали:
P>>Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task? P>>В каких случаях так нельзя сделать и нужно применять ContinueWith?
Q>Например, в тех случаях, когда таску тебе возвращает другой метод, а не ты её конструируешь из делегата.
Не понял. В смысле если первый метод возвращает делегат? В чем отличие? Не мог бы пару строк: первый метод и метод, помещенный в ContinueWith, а то не соображу, что имеешь в виду?
Здравствуйте, 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. Т.е. когда такая схема может быть полезна?
Здравствуйте, Qbit86, Вы писали:
Q>Здравствуйте, Passerby, Вы писали:
P>>А в чем смысл создания метода, возвращающего Task<int>? Здесь проще создать метод, возвращающий int и далее последовательное их выполнение в Task. Т.е. когда такая схема может быть полезна?
Q>Здесь проще, потому что я твой простой код взял для примера. В общем случае у тебя может быть произвольная операция, например, I/O bound. Скажем, чтение 1000000 чисел из файла и их сложение, или скачивание из сети, etc. Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.
Понятно. Спасибо.
Здравствуйте, TK, Вы писали:
TK>Здравствуйте, Sharov, Вы писали:
S>>Пидантизьму ради Async бы добавить в название метода ClosedSourceMethod.
TK>А по возвращаемому значению разве не понятно, что метод может выполняться синхронно?
Причем здесь это? Можно и не добавлять, но методы, которые возвращают task'и обычно имеют суффикс async.
Здравствуйте, Passerby, Вы писали:
P>В каких случаях так нельзя сделать и нужно применять ContinueWith?
ContinueWith используется компилятором при обработке await. Соответственно, всегда когда у тебя в коде есть await, ты можешь сделать аналогичное поведение через ContinueWith. Обычно это менее удобно и потому смысла нет, но иногда может быть весьма актуально, например, если надо программно собрать последовательность асинхронных операций.
Re[2]: Зачем нужен ContinueWith, если в {} можно поместить обе задачи
Здравствуйте, Sharov, Вы писали:
S>>>Пидантизьму ради Async бы добавить в название метода ClosedSourceMethod.
TK>>А по возвращаемому значению разве не понятно, что метод может выполняться синхронно? S>Причем здесь это? Можно и не добавлять, но методы, которые возвращают task'и обычно имеют суффикс async.
Это карго-культ, а не педантизм.
ps
про Task.XXX забыл.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: Зачем нужен ContinueWith, если в {} можно поместить обе задачи
Здравствуйте, Passerby, Вы писали:
P>Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task? P>В каких случаях так нельзя сделать и нужно применять ContinueWith?
Очевидно, что ContinueWith будет полезен во всех остальных случаях, когда обе задачи нельзя поместить в один Task
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Qbit86, Вы писали:
Q>Здесь проще, потому что я твой простой код взял для примера. В общем случае у тебя может быть произвольная операция, например, I/O bound. Скажем, чтение 1000000 чисел из файла и их сложение, или скачивание из сети, etc. Асинхронное чтение из файла против синхронного, но завёрнутого в поток — это не одно и тоже.
синхронного, но завёрнутого в поток — это вообще что? и можно ли вообще читать файлы (или качать из сети) вообще без заворачиваний и потоков?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
S>>Причем здесь это? Можно и не добавлять, но методы, которые возвращают task'и обычно имеют суффикс async. TK>Это карго-культ, а не педантизм. TK>ps TK>про Task.XXX забыл.
Здравствуйте, 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("..."));
Это детали реализации — для потребителя данные методы должны быть равнозначны.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Это карго-культ, а не педантизм.
Этот карго-культ экономит много времени на глупых трудновылавливаемых ошибках, вызванных забытым await. Оно, кстати, не только при просмотре кода полезно, решарпер использует наличие суффикса в одном из своих анализов на предмет как раз забытого await.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Этот карго-культ экономит много времени на глупых трудновылавливаемых ошибках, вызванных забытым await. Оно, кстати, не только при просмотре кода полезно, решарпер использует наличие суффикса в одном из своих анализов на предмет как раз забытого await.
Ещё, когда я вызывают метод Task<T> DoSomethingAsync(), то ожидаю, что вернувшийся таск уже работает и надо только дождаться результата. А если DoSomething() возвращает Task, то большой вопрос, что с ним делать, запускать самому или он уже запущен и где-то работает. Интуитивно ожидается, то вернувшийся таск пока не запущен либо уже синхронно выполнился — непонятно короче.
using System;
using System.Threading;
using System.Threading.Tasks;
internal class Program
{
private static async Task Main(string[] args)
{
var task = DoSomething();
//task.Start();
Console.WriteLine("waiting...");
var result = await task;
Console.WriteLine(result);
}
private static Task<int> DoSomething()
{
return new Task<int>(() =>
{
Thread.Sleep(1000);
return 42;
});
}
}
Здравствуйте, TK, Вы писали:
TK>Здравствуйте, Passerby, Вы писали:
P>>Но зачем нужен ContinueWith, если можно сразу выполнить обе задачи поместив их в один Task? P>>В каких случаях так нельзя сделать и нужно применять ContinueWith?
TK>Очевидно, что ContinueWith будет полезен во всех остальных случаях, когда обе задачи нельзя поместить в один Task
Вопрос в том и состоит: когда обе задачи, выполняющиеся последовательно друг за другом и помещенные в разные Task, нельзя поместить в один Task?
Для себя решил, когда библиотека возвращает Task.
Re[2]: Зачем нужен ContinueWith, если в {} можно поместить о