|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
LRНаверное правильней будет сказать, что UI-поток будет ждать завершения выполнения задачи, которая будет выполняться все же в своем потоке, нет? нет, никакого ожидания не будет, точнее будет то, что называется асинхронным ожиданием, но это по сути метафора к тому, что происходит на самом деле ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 15:43 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
hVosttтам же await, который не блокирует поток. ContinueAwait(false) позволяет выполнить оставшуюся часть метода любым из свободных потоков, даже тем, который был использован для запуска задачи. главное понимать, что Task это не поток. Не, не врубаюсь. Есть UI-поток, он запустил делегат в другом потоке (A) и ждет его завершения. Делегат выполняется в потоке А и запускает DownloadAsync в потоке В При отсутствии ConfigureAwait(false) после завершения DownloadAsync выполнение должно вернуться в поток В и в нем выполниться Compute Поток B - это не поток UI Где я ошибаюсь? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 16:04 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
hVosttнет, никакого ожидания не будет, точнее будет то, что называется асинхронным ожиданием, но это по сути метафора к тому, что происходит на самом деле это да, пусть будет "метафора", но лучше метафора об ожидании, чем об выполнении в UI-потоке hVosttвыполняет сложную вычислительную операцию, думая что она также выполнится асинхронно, но очевидно будет выполняться в UI-потоке о каком выполнении в UI-потоке идет речь? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 16:18 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
LRНаверное правильней будет сказать, что UI-поток будет ждать завершения выполнения задачи, которая будет выполняться все же в своем потоке, нет? Наверное правильнее сказать, что выполнение UI потока будет продолжено в той точке, в которой завершится выполнение задачи. Во время выполнения той задачи UI поток свободно может выполнять другие задачи, те же обслуживания выполнения других событий. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 16:39 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
ЕвгенийВLRНаверное правильней будет сказать, что UI-поток будет ждать завершения выполнения задачи, которая будет выполняться все же в своем потоке, нет? Наверное правильнее сказать, что выполнение UI потока будет продолжено в той точке, в которой завершится выполнение задачи. Во время выполнения той задачи UI поток свободно может выполнять другие задачи, те же обслуживания выполнения других событий. Пожалуй, что и так... Но длинновато, проще сказать, что UI поток будет "поджидать" в той точке...))) Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 16:49 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Блин))) await оператор ожидания. Назовите его GoTo, каллбэк и т.д. и т.п. Слова поток можно не употреблять. Кому как нравится. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 17:42 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Petro123Блин))) await оператор ожидания. Назовите его GoTo, каллбэк и т.д. и т.п. Слова поток можно не употреблять. Кому как нравится. await - не оператор ожидания! ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 18:32 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Shocker.ProЕсть UI-поток, он запустил делегат в другом потоке (A) и ждет его завершения. Он запустил задачу в новом потоке и поставил точку ожидания, очень грубо говоря, подписался на продолжение выполнения синхронного кода в любом месте после await , не важно где внутри задачи тоже, если await вызов не сконфигурирован таким образом, чтобы обработать код продолжения мог любой свободный поток. Никто ничего не ждёт, иными словами. LR правильное слово нашёл для этого: «поджидание» :) Shocker.ProДелегат выполняется в потоке А и запускает DownloadAsync в потоке В DownloadAsync не выполняется ни в каком потоке. Это IO операция. Условно говоря, есть отдельные IO потоки (но это не потоки конечно же), которые сигнализируют о завершении своего выполнения. Shocker.ProПри отсутствии ConfigureAwait(false) после завершения DownloadAsync выполнение должно вернуться в поток В и в нем выполниться Compute В этом месте уже нет потока B. Если ConfigureAwait(false) отсутствует, то завершение будет обрабатывать основной поток, который владеет контекстом синхронизации. https://habr.com/post/107583/ здесь подробней. Shocker.ProПоток B - это не поток UI Где я ошибаюсь? Ты ошибаешься (всё ещё) в том, что считаешь задачу Task потоком. Это не так. Поток дошёл до первого await и пошёл гулять. Он как разнорабочий, залил цементный раствор и пошёл курить, или ещё что-то делать. Мимо проходил другой или тот же самый рабочий, увидел, что цемент застыл и продолжил начатую работу здесь. А главный поток это Прораб, который по умолчанию поручает, чтобы его звали каждый раз, когда длительная операция закончится (застывание цемента, например). Без него ничего не может продолжится, если не сконфигурировано иначе. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 18:52 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
LRо каком выполнении в UI-потоке идет речь? О синхронном коде. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 18:53 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
ЕвгенийВPetro123Блин))) await оператор ожидания. Назовите его GoTo, каллбэк и т.д. и т.п. Слова поток можно не употреблять. Кому как нравится. await - не оператор ожидания! Смешно. Оператор await используется для ожидания Так подходит?)) ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 19:17 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Поможет только внимательный разбор исходников ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 19:25 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
hVostt, в той статье автор пространно размышлял примерно так: "В таск перетекает ExecutionContext, вместе с ним, как часть, SynchronizationContext.Current, и если перетекает действительно "в статусе текущего" - тогда это плохо, ибо, например, вот в таком коде это приведет к (нежелательному) выполнению Compute(data) на UI-потоке". Заканчиваются эти размышления обзором internal-методов в mscorlib и заключительной фразой: "In short, SynchronizationContext.Current does not “flow” across await points." ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 19:25 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Petro123, Тревожное ожидание (лучше бы - тревожная работа (работаешь(отдыхаешь) и ждешь звоночка)) ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 19:26 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
ИзопропилПоможет только внимательный разбор исходников Поможет внимательное прочтение асинхронного ввода/вывода в Windows NT ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 19:27 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
LR, Это зависит от конфигурации await вызова, и работает для кода продолжения, но контекст синхронизации не назначается потоку, как это можно сделать старым способом через Post или через шедулер. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 19:47 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
ViPRosИзопропилПоможет только внимательный разбор исходников Поможет внимательное прочтение асинхронного ввода/вывода в Windows NT этого недостаточно. он сильно проще и логичнее в NT ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 20:16 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
LRhVostt, в той статье автор пространно размышлял примерно так: "В таск перетекает ExecutionContext, вместе с ним, как часть, SynchronizationContext.Current, и если перетекает действительно "в статусе текущего" - тогда это плохо, ибо, например, вот в таком коде это приведет к (нежелательному) выполнению Compute(data) на UI-потоке". Заканчиваются эти размышления обзором internal-методов в mscorlib и заключительной фразой: "In short, SynchronizationContext.Current does not “flow” across await points." вроде как всё понятно автор The internal one (internal to mscorlib) is the one used by most asynchronous functionality exposed from mscorlib, and it optionally allows the caller to suppress the capturing of SynchronizationContext as part of ExecutionContext; corresponding to that, there’s also an internal overload of the Run method that supports ignoring a SynchronizationContext that’s stored in the ExecutionContext, in effect pretending one wasn’t captured (this is, again, the overload used by most functionality in mscorlib). What this means is that pretty much any asynchronous operation whose core implementation resides in mscorlib won’t flow SynchronizationContext as part of ExecutionContext, but any asynchronous operation whose core implementation resides anywhere else will flow SynchronizationContext as part of ExecutionContext. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 20:24 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Изопропилвроде как всё понятно да, и касательно async-методов, следующее же предложение является решающим в цепочке его умозаключений авторI previously mentioned that the “builders” for async methods were the types responsible for flowing ExecutionContext in async methods, and these builders do live in mscorlib, and they do use the internal overloads… as such, SynchronizationContext is not flowed as part of ExecutionContext across awaits ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2018, 20:51 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
hVosttShocker.ProПри отсутствии ConfigureAwait(false) после завершения DownloadAsync выполнение должно вернуться в поток В и в нем выполниться Compute В этом месте уже нет потока B. Если ConfigureAwait(false) отсутствует, то завершение будет обрабатывать основной поток, который владеет контекстом синхронизации. https://habr.com/post/107583/ здесь подробней.Блин, я сам опечатался, когда писал. Имелось ввиду "в поток А". Ок, не будем использовать термин "ожидание", это как-бы условность - да, будем говорит о продолжении. Итак, UI-поток запустил делегат на потоке из пула (А). Когда делегат закончит выполнение, тогда будет продолжение в UI-потоке (а именно, выполнится присвоение button1.Text =) Далее делегат запускает DownloadAsync(). Сам делегат выполняется в потоке А. Так как при вызове DownloadAsync() нет ConfigureAwait(false), то продолжение в делегате после await-а (а именно метод Compute()) должен выполняться в потоке А. Где я не прав? Статья ясности не внесла - там нет каскадного await-а ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2018, 05:09 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
>Petro123, вчера, 19:17 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1300144&msg=21633388][21633388] >...Оператор await используется для ожидания. <Может быть так: В коде вызывающего метода оператор await используется для ожидания завершения кода вызванного метода. Коды других методов, обработчиков сообщений, могут работать асинхронно. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2018, 08:43 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Shocker.ProИтак, UI-поток запустил делегат на потоке из пула (А). Когда делегат закончит выполнение, тогда будет продолжение в UI-потоке (а именно, выполнится присвоение button1.Text =) Ты думаешь, что UI-поток получит управление только в точке вызова Task, т.е. на момент присвоения button1.Text, но это не так. UI-поток подключится после любого await, не важно какой каскад функций был вызван внутри, если не сконфигурировано иначе. Обычно принято в библиотеках везде втыкать ConfigureAwait, чтобы разработчик не получал фризы и дедлоки. Shocker.ProТак как при вызове DownloadAsync() нет ConfigureAwait(false), то продолжение в делегате после await-а (а именно метод Compute()) должен выполняться в потоке А. Где я не прав? Ты всё ещё думаешь, что после выполнения асинхронного метода есть какой-то поток А, который запустил DownloadAsync и теперь сидит ждёт, когда он выполнится :) После запуска асинхронного метода, поток освободился, и где будет выполнятся продолжение метода теперь зависит от ConfigureAwait. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2018, 08:49 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
hVosttТы думаешь, что UI-поток получит управление только в точке вызова Task, т.е. на момент присвоения button1.Text, но это не так. UI-поток подключится после любого await, не важно какой каскад функций был вызван внутри, если не сконфигурировано иначе. Откуда такое заблуждение? Вся та статья как раз и посвящена доказательству того что это не так (что контекст синхронизации не переходит через await, а значит, если вызов async-метода производится не из UI-потока, то и продолжение не будет выполнятся в UI-потоке, что бы там в ConfigureAwait не задавалось). Вот как в этой точке UI-поток может получить управление? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
Разве что так, но ведь разговор идет вовсе не об этом Код: c# 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2018, 09:56 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
hVosttчто после выполнения асинхронного метода есть какой-то поток АТо есть именно этот поток может уже и не существовать, когда возникает необходимость продолжения, ок, это дошло. Я всегда пишу ConfigureAwait(false) кроме начальных вызовов из UI-потока, даже если и не в библиотеках. Получается, что если ConfigureAwait(false) где-то забыл, то мы получим продолжение в контексте синхронизации независимо от глубины вложенности await-ов. При этом если забыли ConfigureAwait(false) на N-ом уровне вложенности, продолжение N-ого уровня выполнится в UI-потоке, и все по цепочке N-1, N-2... обратно к началу вызовов начнет выполняться в UI-потоке, потому что ConfigureAwait(false) разрешит не менять поток при продолжении. Теперь я правильно понял? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2018, 09:57 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
Shocker.Pro, ConfigureAwait(false) просто разрешает выполнять твой контекст в любом потоке, UI-поток не исключение ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2018, 10:32 |
|
Зачем нужен await?
|
|||
---|---|---|---|
#18+
kealon(Ruslan)ConfigureAwait(false) просто разрешает выполнять твой контекст в любом потоке, UI-поток не исключениеConfigureAwait(false) разрешает выполнять продолжение в том же потоке, но меня пока интересует обратная ситуация... ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2018, 10:34 |
|
|
start [/forum/topic.php?fid=20&msg=39684415&tid=1399271]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
141ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 257ms |
0 / 0 |