Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/75: Рейтинг темы: голосов - 75, средняя оценка - 4.69
 Аватар для Toros1992
899 / 554 / 275
Регистрация: 26.11.2015
Сообщений: 1,758
Записей в блоге: 2

Корректный синхронный вызов асинхронного метода

30.07.2020, 10:07. Показов 14448. Ответов 31

Студворк — интернет-сервис помощи студентам
Всем привет. Подскажите, корректно ли вот так превращать асинхронный вызов в синхронный?
C#
1
2
3
4
5
6
        public static T WaitResult<T>(this Task<T> task)
        {
            var t = Task.Run(async () => await task);
            t.Wait();
            return t.Result;
        }
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.07.2020, 10:07
Ответы с готовыми решениями:

Вызов асинхронного метода из события
Присваиваю событию ссылку на метод _mainView.StartBinaryTradeClickEventRaised += new EventHandler(OnStartBrTradeClickEventRaised); ...

Ожидание выполнение асинхронного метода
Всем привет. Помогите разобраться с асинхронным программированием. Пишу приложение для windows store Есть класс. В нем два асинхронных...

Как прекратить выполнение асинхронного метода
Есть форма. По событию mouseUp исполняется следующий код: _isDragging = false; if (_isClickOnly) { ...

31
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
30.07.2020, 11:38
Toros1992, нет. Wait в асинхронном коде не используется. Очень грубо говоря async/await опирается на колбэки, смазанные хорошим слоем сахара.

PS: Хочется получить результат асинхронного метода .Result - ваш друг. Без Wait.
1
 Аватар для Toros1992
899 / 554 / 275
Регистрация: 26.11.2015
Сообщений: 1,758
Записей в блоге: 2
30.07.2020, 11:50  [ТС]
А чем черевато?

Добавлено через 40 секунд
И метод, который использует wait не асинхронный
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
30.07.2020, 11:52
Цитата Сообщение от freeba Посмотреть сообщение
Result - ваш друг. Без Wait.
а в чем разница по вашему?
Result сам будет делать Wait, если вы не сделаете
1
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
30.07.2020, 11:55
Цитата Сообщение от Toros1992 Посмотреть сообщение
И метод, который использует wait не асинхронный
Судя по исходнику - более чем асинхронный.

Цитата Сообщение от Toros1992 Посмотреть сообщение
А чем черевато?
Wait блокирует поток. А исходя из идеи async/await когда метод может начаться в одном потоке, а закончится в другом... Для Winforms/WPF проблем не будет. А вот в веб/службах можно поиметь серьезные проблемы с производительностью и исчерпанием свободных потоков в пуле.

PS: Можно конечно везде расставлять ConfigureAwait(true); Но тогда всю мощь async/await не прочувствовать.
0
 Аватар для Toros1992
899 / 554 / 275
Регистрация: 26.11.2015
Сообщений: 1,758
Записей в блоге: 2
30.07.2020, 11:58  [ТС]
Цитата Сообщение от freeba Посмотреть сообщение
Судя по исходнику - более чем асинхронный.
Метод WaitResult синхронный. Я про него. Ему передается таска, на которой и вызывается Wait. Или вы про чтото иное?
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
30.07.2020, 12:01
Цитата Сообщение от КОП Посмотреть сообщение
Result сам будет делать Wait, если вы не сделаете
Эм. Не совсем так.

Добавлено через 1 минуту
Toros1992, Про него. Но Wait не нужен.
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
30.07.2020, 12:03
Цитата Сообщение от freeba Посмотреть сообщение
Эм. Не совсем так.
поясните, какая будет разница если я в исходном коде выкину строку с Wait?
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
30.07.2020, 12:10
Цитата Сообщение от КОП Посмотреть сообщение
поясните, какая будет разница если я в исходном коде выкину строку с Wait?
Ух. Исключая wpf/winforms, когда вы дергаете wait вы блокируете поток входа выполнения async, но продолжаться await может не в том потоке который его вызывал, оставляя блокировку на стартовом потоке.

Обычно это не страшно (блокировка она внутри CLR), но если вы делаете приложение которое работает месяцами/годами без рестарта, вы можете полностью исчерпать пул потоков. И приложение падая будет вам гордо сообщать что нибудь вроде OutOfMemory бро, при свободных сотне гигов оперативки.
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
30.07.2020, 12:24
Цитата Сообщение от freeba Посмотреть сообщение
когда вы дергаете wait вы блокируете поток входа выполнения async
так же как и дергая Result. Раздел ремарки
https://docs.microsoft.com/en-... k_1_Result

так в чем разница то? вот уберу я Wait - мне Result заблокирует поток, оставлю Wait - сам Wait и заблокирует.
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
30.07.2020, 13:21
КОП, Это не имеет отношения к потрохам async/await. Это всего лишь пример, иллюстрирующий совершенно иную вещь. Result не блокирует поток, он блокирует контекст исполнения, если можно так выразится.

Вы мне говорите про абстракции, я вам говорю как оно внутре работает. Оно не всегда совпадает...
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
30.07.2020, 13:51
freeba, пока не до конца понял про что вы, вот такие вопросы возникли
Цитата Сообщение от freeba Посмотреть сообщение
Result не блокирует поток
то есть это предложение в справке невено или неточно?
it is equivalent to calling the Wait method.
Цитата Сообщение от freeba Посмотреть сообщение
он блокирует контекст исполнения, если можно так выразится.
поясните пожалуйста, не уверен что понимаю о чем вы
Цитата Сообщение от freeba Посмотреть сообщение
Вы мне говорите про абстракции, я вам говорю как оно внутре работает. Оно не всегда совпадает...
можете навялять простой кусочек кода где наглядно будет видна разница? никак не могу себе представить

Добавлено через 14 минут
Цитата Сообщение от freeba Посмотреть сообщение
Оно не всегда совпадает...
согласно сорсам Result и Wait оба вызывают InternalWait для ожидания.
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
30.07.2020, 14:00
Цитата Сообщение от КОП Посмотреть сообщение
можете навялять простой кусочек кода где наглядно будет видна разница? никак не могу себе представить
Это будет очень большой кусочек, я слишком ленивый сегодня. Но если таки будут пожелания, готов расписать в чем разница между асинхронщиной и честным паралелеизмом, к которым наш Wait и относится.

Цитата Сообщение от КОП Посмотреть сообщение
то есть это предложение в справке невено или неточно?
it is equivalent to calling the Wait method.
Это и верно и точно, но в контексте паралелизма. Асинхронность != Паралельность и сие превозносит иногда забавные сюрпризы.

Цитата Сообщение от КОП Посмотреть сообщение
поясните пожалуйста, не уверен что понимаю о чем вы
Ну вы таки сами напросились. Попробую ясно объяснить.

Как только мы помечаем метод async - компилятор в тот же момент из привычного последовательного потока команд, превращает наш метод в конечный автомат, причем весьма специфический и опирающийся на пул потоков процесса (это важно). Конечный автомат это круто и эффективно, но это черный ящик, которому мы скармливаем исходные данные и в итоге получаем результат. Вы рассуждаете в контексте абстракций вокруг этого черного ящика и в целом все логично. Скормили данные - получили результат. Но, внутри этого ящика может случится такая фигня, что поток обработки изменится и мы отправив данные в один поток, получим их из другого (так бывает не всегда, но бывает).

Т.е. мы не пострадаем, мы в любом случае получаем свой результат, но контроль над входным потоком теряется. И если CLR помечает его как busy - из пула потоков нам его уже не отдадут. И вот здесь возникает проблема, если просто вызвать Result - то проблем нет, CLR обо всем позаботится, но если мы дергаем Wait, то компилятор будет предполагать, что мы знаем, что делаем и заблокирует входной поток. Если результат нам вернется из него же, то алилуя, проблем нет, а вот если он вернется из другого? По факту, это та же история как и "пропадающие" эксепшены из асинхронных методов. В целом не смертельно, но без понимания как оно работает, можно получить несколько неприятных моментов.
2
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,227
30.07.2020, 14:04
Toros1992, а зачем вам этот метод расширения вообще нужен?
Вот дергаете вы на существующей таске:
C#
1
2
3
4
5
6
7
8
9
10
public static T WaitResult<T>(this Task<T> task)
        {
            var t = Task.Run(async () => await task);
            t.Wait();
            return t.Result;
        }
 
// пример
var task = SomeMethodAsync();
var res = task.WaitResult<object>();
Чем это отличается от этого?
C#
1
2
var task = SomeMethodAsync();
task.Wait();
Типа под капотом WaitResult: смотри какие я умею делать бутерброды - делаю масло масляное, а потом еще на это масло сахар в виде Task.Run(async () => await task);
Тогда лучше с комментом - этот метод втихую берет поток из пула
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
30.07.2020, 14:10
Цитата Сообщение от freeba Посмотреть сообщение
Это будет очень большой кусочек, я слишком ленивый сегодня.
очень бы хотелось увидеть и пощупать.
Цитата Сообщение от freeba Посмотреть сообщение
Асинхронность != Паралельность и сие превозносит иногда забавные сюрпризы.
в целом думаю я понимаю разницу, я не понимаю откуда она должна взяться от замены Result на Wait, так как оба после пары ифов вызовут InternalWait.
0
 Аватар для Toros1992
899 / 554 / 275
Регистрация: 26.11.2015
Сообщений: 1,758
Записей в блоге: 2
30.07.2020, 14:12  [ТС]
IamRain, Я это не делаю еще. Я просто пытаюсь разобраться как безопасно синхронно вызвать асинхронный метод. И я слышал про проблемы, связанные с этим, если код крутиться на веб приложении. Обертку таски в Task.Run(async () => await task) я вычитал на StackOverfow. Я же не заявляю, что так делать надо. Просто спрашиваю

freeba, А что делать тогда с непараметризованной таской? У нее нет Result
К примеру так:
C#
1
2
3
4
5
        public static void WaitResult(this Task task)
        {
            var t = Task.Run(async () => await task);
            t.Wait();
        }
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,227
30.07.2020, 14:19
Цитата Сообщение от КОП Посмотреть сообщение
я не понимаю откуда она должна взяться от замены Result на Wait
Я вот тоже не вижу разницы.
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
30.07.2020, 14:24
Цитата Сообщение от КОП Посмотреть сообщение
очень бы хотелось увидеть и пощупать.
Ух, ок, как нибудь сделаю FAQ с описанием чем паралелизм отличается от асинхронного подхода.

Цитата Сообщение от Toros1992 Посмотреть сообщение
А что делать тогда с непараметризованной таской? У нее нет Result
Если такая ситуация возникает, то вы просто зря используете async. ContinueWith либо IAsyncResult решает такие вещи, в зависимости от архитектуры. Но в целом исходный код похож скорее на костыль, чем на реальный. Без веской причины так не делают.

Что мешает сделать так?
C#
1
2
3
4
 public static Task WaitResult(this Task task)
        {
            return Task.Run(async () => await task);
        }
PS: или еще лучше:

C#
1
2
3
4
 public static async Task WaitResult(this Task task)
        {
            await task;
        }
1
 Аватар для Toros1992
899 / 554 / 275
Регистрация: 26.11.2015
Сообщений: 1,758
Записей в блоге: 2
30.07.2020, 14:30  [ТС]
freeba, конкретный пример. в Microsoft.WindowsAzure.Storage для NetCore нет синхронных методов работы с AzureTable
В итоге код выглядит как то так:
C#
1
2
CloudTable table = cloudTableClient.GetTableReference(configuration["Spec.VocValue.DefaultsTable"]);
Task.Run(async () => await table.CreateIfNotExistsAsync()).Wait();
То есть если таблицы не существует, мне надо дождаться ее создания. Как бы вы в таком случае поступили?

Добавлено через 58 секунд
нет, это плохой пример. Там возвращается bool. Прошу прощения
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
30.07.2020, 14:32
Цитата Сообщение от freeba Посмотреть сообщение
FAQ с описанием чем паралелизм отличается от асинхронного подхода.
причем тут параллелизм и асинхронный код? мы разницу между Wait и Result ищем, это всего лишь методы/свойства таска. В каком контекста этот таск запустили и с какими параметрами тут роли не играет

Ощущение что мы про разное говорим

т.е. между
C#
1
2
3
4
5
6
        public static T WaitResult<T>(this Task<T> task)
        {
            var t = Task.Run(async () => await task);
            t.Wait();
            return t.Result;
        }
и
C#
1
2
3
4
5
        public static T WaitResult<T>(this Task<T> task)
        {
            var t = Task.Run(async () => await task);
            return t.Result;
        }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.07.2020, 14:32
Помогаю со студенческими работами здесь

Принцип работы асинхронного метода BeginReceive
Здравствуйте. Можете объяснить как работает BeginReceive у сокетов? Сначала метод вызывается, указываются параметры; затем он ждет...

Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода
В базовом классе метод помечен как virtual. Насколько я понял из книги: override означает, что метод не утрачивает связи с базовым...

Как из асинхронного метода получить объект?
Вопрос Как из асинхронного метода получить объект? Используется - Microsoft.EntityFrameworkCore; -...

Юнит-тест для асинхронного метода
Доброго всем времени суток! В теме &quot;Логирование при использовании многопоточности&quot; уважаемый kolorotur помог мне написать...

Передача параметров и возврат значений из асинхронного метода
Для примера есть метод, который по замыслу должен в асинхронном режиме возвращать содержимое страницы. private async...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru