Есть ли будущее у DELPHI?
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.43] |
|
|
Правила раздела:
| Страницы: (245) « Первая ... 139 140 [141] 142 143 ... 244 245 ( Перейти к последнему сообщению ) |
Есть ли будущее у DELPHI?
|
Сообщ.
#2101
,
|
|
|
|
Цитата MyNameIsIgor @ Ты Node.js видел? Понимаешь, все эти async/await - это синтаксический сахар, который разворачивается в точности в коллбэчный код а-ля Node.js. ExpressJS'ом баловался (этакие рельсы для ноды), но там это как-то по-другому выглядело, явно передавались лямбдами коллбэки. Цитата MyNameIsIgor @ А про второй код... вот если честно, то я не в курсе, упустил как-то этот момент: можно ли помечать функцию async, если внутри неё нет await? Если предположить, что можно, то вывод будет ![]() ![]() 00:00:00 calc 1 00:00:03 done 1 00:00:03 calc 2 00:00:06 done 2 00:00:06 foo 00:00:06 bar Я изначально подумал, что async это аналог той же go, только идет как свойство метода, а не в точке вызова (т.е. async-метод всегда запускается асинхронно), поэтому расчитывал, что результат будет такой же, как и в первом случае. |
|
Сообщ.
#2102
,
|
|
|
|
Цитата MyNameIsIgor @ Вот чтобы получить такой эффект как раз и нужно ![]() ![]() async void foo() { await Task.WaitAll(longCalc(1), longCalc(2)); log("foo"); } о чём спрашивал jack128. Ясно... Как-то это все запутано сделано в этих ихних сишарпах =) |
|
Сообщ.
#2103
,
|
|
|
|
Цитата korvin @ ExpressJS'ом баловался (этакие рельсы для ноды), но там это как-то по-другому выглядело, явно передавались лямбдами коллбэки. Грубо говоря, здесь всё, что идёт за await, и есть этот самый коллбэк. Цитата korvin @ Я изначально подумал, что async это аналог той же go Не, это аннотация метода, указание на присутствие внутри await'а. Т.е. указание, что внутри метода запускается задача, а управление из метода возвращается до того, как задача завершится. |
|
Сообщ.
#2104
,
|
|
|
|
Цитата MyNameIsIgor @ А про второй код... вот если честно, то я не в курсе, упустил как-то этот момент: можно ли помечать функцию async, если внутри неё нет await? В общем помечать-то можно, но это дает только предупреждение о том, что async-блок без await'а будет выполнен синхронно. Я тут провел некоторые тесты, в результате: ![]() ![]() ~/go $ mono test.exe 27.10.2012 18:18:26 bar 27.10.2012 18:18:26 calc 1 27.10.2012 18:18:29 done 1 27.10.2012 18:18:29 calc 2 27.10.2012 18:18:32 done 2 27.10.2012 18:18:32 foo 1 2 -------- 27.10.2012 18:18:36 calc 1 27.10.2012 18:18:36 bar 27.10.2012 18:18:36 calc 2 27.10.2012 18:18:39 done 1 27.10.2012 18:18:39 done 2 27.10.2012 18:18:39 foo 1 2 -------- 27.10.2012 18:18:46 calc 1 27.10.2012 18:18:46 bar 27.10.2012 18:18:49 done 1 27.10.2012 18:18:49 calc 2 27.10.2012 18:18:52 done 2 27.10.2012 18:18:52 foo 1 2 -------- 27.10.2012 18:18:56 bar 27.10.2012 18:18:56 calc 1 27.10.2012 18:18:59 done 1 27.10.2012 18:18:59 calc 2 27.10.2012 18:19:02 done 2 27.10.2012 18:19:02 foo 1 2 ~/go $ в результате Test3 оказался удачным лишь наполовину: + с одной стороны действительно можно вместо двух await-вызовов асинхронных таск вызвать две синтхронные внутри одной асинхронной, как я и предполагал с самого начала - с другой МС перемудрили с этими async/await т.к. await нельзя вызвать в синхронном методе, соответственно пришлось пометить Test3b как асинхронный, а в конце Main добавить Sleep, чтобы она дождалась выполнения Test3b (да и вообще во всех тестах, впрочем, это скорее всего по незнанию и попытке писать на C# как на Go =)) Добавлено А вот аналогичный, но не идентичный код на Go: http://ideone.com/nFkfZM Я специально не стал его переписывать один в один к шарповому, чтоб показать, почему я считаю, что МС перемудрили с async/await =) Кроме того обратите внимания на foo3b и test3b, благодаря такому распространенному приему нет необходимости в десятисекундной задержке для этой функции =) Результат выполнения соответствует шарповому: ![]() ![]() ~/go $ go run test.go 18:56:10 bar 18:56:10 calc 1 18:56:13 done 1 18:56:13 calc 2 18:56:16 done 2 18:56:16 foo 1 2 -------- 18:56:20 bar 18:56:20 calc 1 18:56:20 calc 2 18:56:23 done 1 18:56:23 done 2 18:56:23 foo 1 2 -------- 18:56:30 bar 18:56:30 calc 1 18:56:33 done 1 18:56:33 calc 2 18:56:36 done 2 18:56:36 foo 1 2 -------- 18:56:40 bar 18:56:40 calc 1 18:56:43 done 1 18:56:43 calc 2 18:56:46 done 2 18:56:46 foo 1 2 ~/go $ Эх, жаль делфисты кончились, интересно как там у них дела с конкурентностью =) |
|
Сообщ.
#2105
,
|
|
|
|
Цитата korvin @ с одной стороны действительно можно вместо двух await-вызовов асинхронных таск вызвать две синтхронные внутри одной асинхронной, как я и предполагал с самого начала Я и не говорил, что нельзя. Я говорил о разной семантике ![]() ![]() await foo(); await bar(); и ![]() ![]() foo(); bar(); |
|
Сообщ.
#2106
,
|
|
|
|
Цитата MyNameIsIgor @ Я и не говорил, что нельзя. Я говорил о разной семантике ![]() ![]() await foo(); await bar(); и ![]() ![]() foo(); bar(); Естественно, иначе бы и ключевого слова не было =) Но я-то говорю о равнозначности семантики ![]() ![]() await fooAsync(); await barAsync(); и ![]() ![]() foo(); bar(); и выглядит это несколько странно, как двойное отрицание. Добавлено Т.е. для меня это выглядит так: вначале было все синхронно, потом запилили поддержку асинхронности, а потом вместо добавления нормального способа синхронизации (STM или Message Passing), добавили возможность вызывать асинхронный метод синхронно, причем сделать это можно только внутри асинхронного кода, который в итоге тоже нужно таким же способом синхронизировать (т.к. в конечном счете Main не может быть асинхронным), но это можно сделать только внутри асинхронного метода... И как в конечном счете это синхронизировать с Main, непонятно. Попахивает рекурсивным костылизмом. =)) P.S. Кстати, серьезно, как в моем примере избавится от таймера в конце Main? |
|
Сообщ.
#2107
,
|
|
|
|
Цитата MyNameIsIgor @ Я и не говорил, что нельзя. Я говорил о разной семантике Цитата korvin @ Естественно, иначе бы и ключевого слова не было =) Но я-то говорю о равнозначности семантики ![]() Цитата korvin @ P.S. Кстати, серьезно, как в моем примере избавится от таймера в конце Main? Возвращать из Test3b не void, а Task<void>. А вообще да, ежели кто вернёт void - обломс |
|
Сообщ.
#2108
,
|
|
|
|
Цитата MyNameIsIgor @ Возвращать из Test3b не void, а Task<void>. Эм... Можешь показать как именно, а то че-то не соображу? Добавлено Цитата MyNameIsIgor @ Цитата MyNameIsIgor @ Я и не говорил, что нельзя. Я говорил о разной семантике Цитата korvin @ Естественно, иначе бы и ключевого слова не было =) Но я-то говорю о равнозначности семантики ![]() Я там имел в виду синхронные foo и bar (которые без суффикса async). Т.е. если бы async и await не бы ли бы так тесно связаны (например хотя бы async-метод без await'а внутри оставался бы асинхронным), то код ![]() ![]() void foo() { print("foo") } void bar() { print("bar") } async void m() { foo() bar() } и код ![]() ![]() async void foo() { print("foo") } async void bar() { print("bar") } async void m() { await foo() await bar() } были бы полностью равнозначны. И в принципе они и так равнозначны, просто из-за дурацкого решения приходится делать чуть сложнее. |
|
Сообщ.
#2109
,
|
|
|
|
Цитата korvin @ И в принципе они и так равнозначны Да не равнозначный они! Код после await вызывается вообще в другом контексте. |
|
Сообщ.
#2110
,
|
|
|
|
Цитата MyNameIsIgor @ Да не равнозначный они! Код после await вызывается вообще в другом контексте. В каком другом? |
|
Сообщ.
#2111
,
|
|
|
|
Хм... че-то вы мудрите...
Да, асихронку в новом C# я еще не юзал, но доку уже скурил, поэтому может я не прав. Вот мое виденье асихронки: ![]() ![]() int thr1 = await foo1(); int thr2 = await foo2(); Console.Write("Hello!"); int thr3 = await foo3(); // До этого места все три потока запускаются ОДНОВРЕМЕННО (почти) и вывод "Hello!". Console.Write(thr2); // Использована переменная thr2. //Основной поток останавливается до ожидания завершения foo2(), чтобы вывести значение. |
|
Сообщ.
#2112
,
|
|
|
|
Цитата Keepun @ Хм... че-то вы мудрите... Да, асихронку в новом C# я еще не юзал, но доку уже скурил, поэтому может я не прав. Вот мое виденье асихронки: ![]() ![]() int thr1 = await foo1(); int thr2 = await foo2(); Console.Write("Hello!"); int thr3 = await foo3(); // До этого места все три потока запускаются ОДНОВРЕМЕННО (почти) и вывод "Hello!". Console.Write(thr2); // Использована переменная thr2. //Основной поток останавливается до ожидания завершения foo2(), чтобы вывести значение. Плохо скурил ![]() ![]() using System; using System.Threading; using System.Threading.Tasks; namespace Example { public class Program { private static Task<int> Foo(int x, int delay) { return Task.Factory.StartNew<int>(() => { Console.WriteLine("{0} starting {1}", DateTime.Now, x); Thread.Sleep(delay * 1000); Console.WriteLine("{0} returning {1}", DateTime.Now, x); return x; }); } private static async void Test() { int thr1 = await Foo(1, 4); int thr2 = await Foo(2, 3); Console.WriteLine("Hello!"); int thr3 = await Foo(3, 2); Console.WriteLine(thr2); } public static void Main(string[] args) { Test(); Thread.Sleep(15000); Console.WriteLine("{0} done", DateTime.Now); } } } ![]() ![]() ~/go $ mono keepun.exe 27.10.2012 21:45:30 starting 1 27.10.2012 21:45:34 returning 1 27.10.2012 21:45:34 starting 2 27.10.2012 21:45:37 returning 2 Hello! 27.10.2012 21:45:37 starting 3 27.10.2012 21:45:39 returning 3 2 27.10.2012 21:45:45 done ~/go $ Добавлено Цитата Keepun @ Основной поток останавливается до ожидания завершения foo2(), чтобы вывести значение. А если убрать Thread.Sleep(15000) из Main, то ![]() ![]() ~/go $ mono keepun.exe 27.10.2012 21:48:54 starting 1 27.10.2012 21:48:54 done ~/go $ |
|
Сообщ.
#2113
,
|
|
|
|
Цитата korvin @ Цитата MyNameIsIgor @ Да не равнозначный они! Код после await вызывается вообще в другом контексте. В каком другом? Хз в каком. Я же говорил - вызывается из пула потоков. |
|
Сообщ.
#2114
,
|
|
|
|
korvin, а mono тут причем? Ему еще рано нормально async/await поддерживать.
Нужна самая последняя Студия, чтоб точно о чем-то заявлять. |
|
Сообщ.
#2115
,
|
|
|
|
Цитата MyNameIsIgor @ Хз в каком. Я же говорил - вызывается из пула потоков. И какие отличия это дает? =) Добавлено Цитата Keepun @ korvin, а mono тут причем? Ему еще рано нормально async/await поддерживать. Нужна самая последняя Студия, чтоб точно о чем-то заявлять. мне нечего ответить на это безусловно обоснованное заявление признанного специалиста по .NET, C# и Mono, который как-то странно курил документацию. |