Комментарии 16
То есть, await — простой синтаксический сахар над ContinueWith, который, помимо всего прочего, умеет удобно обрабатывать исключения.«Простым синтаксическим сахаром» он будет после ConfigureAwait(false), т. к. ContinueWith вызовет continuation на потоке из пула. А так он ещё и захватывает контекст синхронизации и далее по тексту.
Ещё забыли написать, что до EAP был паттерн с IAsyncResult.
Так же следует добавить, что можно await-ить всякий хлам, который вообще целиком и полностью живёт в UI-потоке и сигнализирует о своём завершении через TaskCompletionSource. Очень удобно для анимаций, диалогов и во время инициализации приложения, когда не ясно, что в каком порядке отработает.
Ну и must-read документ по TAP от MS.
+12
После сравнения с jquery вроде бы и понятно стало. Но все равно в примере с await асинхронности выполнения не видно. В данном случае строка
всегда будет выполнена быстрее, чем
независимо от скорости отрабатывания таска.
Что скажете?
Console.WriteLine("Hello world!");
всегда будет выполнена быстрее, чем
Console.WriteLine("Got some data");
независимо от скорости отрабатывания таска.
Что скажете?
0
Да, всё именно так. Собственно, цель паттерна async/await — позволить писать асинхронный код в привычном, последовательном стиле: весь код после await неявно становится одним большим колбэком. Плюс подхода в том, что вызывающий поток работает до первого await, а после этого возвращается в пул потоков и может быть использован повторно (на самом деле всё несколько сложнее, тут ещё много магии с SynchronizationContext, но в принципе как-то так). Но при этом никто не запрещает завести столько Task'ов, сколько нужно, и собрать их в одном месте при помощи Task.WhenAll или Task.WhenAny.
+1
Вот теперь все встало на свои места. Как говорится, на пальцах. Спасибо!
0
Плюс подхода в том, что вызывающий поток работает до первого await, а после этого возвращается в пул потоков
Не совсем точно. До первого await и «обратно» по колстэку до точки «входа», потому что ж таски-то нужно еще повозвращать.
0
(Похоже, нужно сделать шаблончик для комментария к постам про
Must read: Concurrency in C# Cookbook
async/await
)Must read: Concurrency in C# Cookbook
+1
Вот тут классно про async/await да еще и в глубинах покопался, но лучше посмотреть весь курс www.youtube.com/watch?v=fi_N_ghu4Ug&list=PLvItDmb0sZw-sOL6sOsEnSJ8etu7Kbgko&index=15
0
private Task<string> DownloadStringWithWebClientAsync(System.Net.WebClient client, Uri url)
{
var tcs = new TaskCompletionSource<string>();
client.DownloadStringCompleted += (_s, _e) =>
{
if (_e.Cancelled)
tcs.TrySetCanceled();
else if (_e.Error != null)
tcs.TrySetException(_e.Error);
else
tcs.TrySetResult(_e.Result);
};
client.DownloadStringAsync(url);
return tcs.Task;
}
Вот такой код будет корректным для DownloadStringAsync? (Подразумевается, что в реальном коде добавится отписка от события и проверка, что скачался «свой» url.)
0
Да многие не понимают вообще как работает async/await, и равняют декларацию метода async как гарантию фоновой работы :)
0
Вот бы такой режим, чтобы по умолчанию все async использовались как await в месте вызова, ну и придется ввести ключевое слово «nowait». А то иногда 80% async-функций вызываются с await и писать его везде опять же утомляет. Ну и инкапсуляция была бы чище — можно не меняя сигнатуры вызова, изменить саму функцию.
-1
По поводу полностью асинхронных методов:
Мое мнение — особо смысла в этом нет. Visual Studio справедливо подмечает, что async метод, не использующий await, будет выполняться последовательно (синхронно). А таких методов большинство.
По сути вся соль не в async методах, а в том, что они возвращают Task. Хочешь — жди результат сразу, хочешь — запусти еще один метод параллельно и дождись, пока отработает и то и то.
А вызвать любой метод асинхронно, в принципе, не так и сложно — нужно вызов просто пережать в Task.Run.
Мое мнение — особо смысла в этом нет. Visual Studio справедливо подмечает, что async метод, не использующий await, будет выполняться последовательно (синхронно). А таких методов большинство.
По сути вся соль не в async методах, а в том, что они возвращают Task. Хочешь — жди результат сразу, хочешь — запусти еще один метод параллельно и дождись, пока отработает и то и то.
А вызвать любой метод асинхронно, в принципе, не так и сложно — нужно вызов просто пережать в Task.Run.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Недопонимание про async/await и многопоточность в C#