Есть ли будущее у DELPHI?
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.43] |
|
|
Правила раздела:
| Страницы: (245) « Первая ... 138 139 [140] 141 142 ... 244 245 ( Перейти к последнему сообщению ) |
Есть ли будущее у DELPHI?
|
Сообщ.
#2086
,
|
|
|
|
В том, что await вернёт управление из обрамляющей функции. Т.е. на самом деле await преобразует этот код во что-то такое ![]() ![]() return File.ReadAllTextAsync('myfile1').then( content1 => File.ReadAllTextAsync('myfile2').then( content2 => /* что-то морщим */)); Т.е. после вызова ReadAllTextAsync управление возвращается из обрамляющей функции. А всё ниже следующее суётся в лямбду и вызывается из пула потоков по окончанию операции. Тут расписано. Там и jack128 засветился |
|
Сообщ.
#2087
,
|
|
|
|
Т.е. грубо говоря, в таком примере:
![]() ![]() private async void foo() { TextBox.Text = await new WebClient().DownloadStringTaskAsync("http://habrahabr.ru/"); bar(); } foo(); gee(); если DownloadStringTaskAsync будет выполняться долго, то gee выполнится до нее, но bar() -- только после DownloadStringTaskAsync? |
|
Сообщ.
#2088
,
|
|
|
|
korvin, да. Вот я и протестую...
|
|
Сообщ.
#2089
,
|
|
|
|
Хм... а в Go я бы это же написал так:
![]() ![]() func foo() { TextBox.Text = new WebClient().DownloadString("http://habrahabr.ru/") bar() } go foo() gee() в чем разница? Добавлено Т.е. ![]() ![]() private async void foo() { TextBox.Text = new WebClient().DownloadString("http://habrahabr.ru/"); bar(); } foo(); gee(); =/ |
|
Сообщ.
#2090
,
|
|
|
|
Цитата korvin @ Хм... а в Go я бы это же написал так в чем разница? В том, что ты создаёшь goroutine которая суть легковесный поток. |
|
Сообщ.
#2091
,
|
|
|
|
Цитата MyNameIsIgor @ В том, что ты создаёшь goroutine которая суть легковесный поток. Да при чем тут сущности и терминология? Я там же ниже привел код на C#. Добавлено Т.е. я бы понял, если б в ![]() ![]() var a = await File.ReadAllTextAsync('myfile1'); var b = await File.ReadAllTextAsync('myfile2'); foo(a, b) функции чтения выполнялись бы конкурентно, а инициализация переменных их значениями и вызов foo — последовательно. Но ты говоришь, что чтение второго файла начнется только после первого. Вот мне и не понятно зачем городить это огород, если можно просто вызвать обычные методы. |
|
Сообщ.
#2092
,
|
|
|
|
Цитата korvin @ Да при чем тут сущности и терминология? Я, вообще-то, про семантику... Цитата korvin @ Вот мне и не понятно зачем городить это огород, если можно просто вызвать обычные методы. Вызов обычных методов, в отличие от вызова с await, не вернёт управление из обрамляющей функции, т.е. заблокирует поток. |
|
Сообщ.
#2093
,
|
|
|
|
Так тут нет никакой обрамляющей функции.
Ладно, допустим 1. ![]() ![]() async int longCalc(int x) { sleep(3); log(x); return x; } async void foo() { var a = await longCalc(1); var b = await longCalc(2); log("foo"); } void bar() { log("bar"); } void main() { foo(); bar(); } 2. ![]() ![]() int longCalc(int x) { log("calc", x) sleep(3); log("done", x); return x; } async void foo() { var a = longCalc(1); var b = longCalc(2); log("foo"); } void bar() { log("bar"); } void main() { foo(); bar(); } в первом случае вывод будет таким: ![]() ![]() 00:00:00 calc 1 00:00:00 bar 00:00:03 done 1 00:00:03 calc 2 00:00:06 done 2 00:00:06 foo ? если нет, то какой? если да, то какой вывод будет во втором случае? |
|
Сообщ.
#2094
,
|
|
|
|
korvin, во-первых, async функция может возвращать либо void, либо Task<ResultType>.
Во-вторых, async нужен только когда внутри функции используется await - вот он и будет из этой async-функции возвращать управление. В-третьих, ты чего сказать то пытаешься? |
|
Сообщ.
#2095
,
|
|
|
|
Цитата MyNameIsIgor @ korvin, во-первых, async функция может возвращать либо void, либо Task<ResultType>. Во-вторых, async нужен только когда внутри функции используется await - вот он и будет из этой async-функции возвращать управление. В-третьих, ты чего сказать то пытаешься? ![]() Да я не сказать, я понять пытаюсь. =) Никогда не видел такой реализации асинхронности. Добавлено Но что насчет вывода первого примера? Он такой будет, как я предположил? |
|
Сообщ.
#2096
,
|
|
|
|
Ну, вот если в первом случае longCalc будет возвращать нечто с методом GetAwaiter(), например, тот же Task, и проставить вывод как во втором случае (который ты наверняка забыл), то получим такой код
![]() ![]() Task<int> longCalc(int x) { return Task.Factory.StartNew<int>( () => { log("calc", x) sleep(3); log("done", x); return x; }; } async void foo() { var a = await longCalc(1); var b = await longCalc(2); log("foo"); } void bar() { log("bar"); } void main() { foo(); bar(); } Его вывод может быть таким ![]() ![]() 00:00:00 bar 00:00:00 calc 1 00:00:03 done 1 00:00:03 calc 2 00:00:06 done 2 00:00:06 foo Может потому, что из-за конкуренции потоков мы не знаем, что произойдёт раньше - вызов bar или старт таска, созданного в longCalc. |
|
Сообщ.
#2097
,
|
|
|
|
Цитата MyNameIsIgor @ проставить вывод как во втором случае (который ты наверняка забыл) Не забыл, а не знал какой он будет =) Цитата если да, то какой вывод будет во втором случае? |
|
Сообщ.
#2098
,
|
|
|
|
Цитата korvin @ Никогда не видел такой реализации асинхронности. Ты Node.js видел? Понимаешь, все эти async/await - это синтаксический сахар, который разворачивается в точности в коллбэчный код а-ля Node.js. Добавлено А про второй код... вот если честно, то я не в курсе, упустил как-то этот момент: можно ли помечать функцию 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 |
|
Сообщ.
#2099
,
|
|
|
|
Цитата MyNameIsIgor @ Может потому, что из-за конкуренции потоков мы не знаем, что произойдёт раньше - вызов bar или старт таска, созданного в longCalc. Не, то, что первые две строчки могут поменяться местами в зависимости от фазы Луны, я знал, меня интересовали остальные, т.к. изначально я предполагал, что будет так: ![]() ![]() 00:00:00 bar 00:00:00 calc 1 00:00:00 calc 2 00:00:03 done 1 00:00:03 done 2 00:00:03 for (причем тут уже первые три строчки могут быть в разном порядке) |
|
Сообщ.
#2100
,
|
|
|
|
Цитата korvin @ причем тут уже первые три строчки могут быть в разном порядке Вот чтобы получить такой эффект как раз и нужно ![]() ![]() async void foo() { await Task.WaitAll(longCalc(1), longCalc(2)); log("foo"); } о чём спрашивал jack128. Да, здесь longCalc возвращают Task'и, а не int'ы. |