Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
awp-sirius
58 / 58 / 41
Регистрация: 01.05.2012
Сообщений: 500
1

Task.Wait async Метод

09.09.2016, 13:23. Просмотров 519. Ответов 11
Метки нет (Все метки)

Всем привет. Нужна помощь.
Я в сеттере (нужно именно тут) создаю таск
C#
1
Task task = new Task(Load);
Сам лоад асинхронный:
C#
1
private async void Load()
Соответственно внутри есть await.

В сеттере выполняю:
C#
1
2
task.Start();
task.Wait();
Запускается и начинает ждать - всё ок. Но когда в методе Load доходит до await почему-то выходит с Wait.
И два потока продолжают выполняться параллельно....... Почему так и как быть?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.09.2016, 13:23
Ответы с готовыми решениями:

Task.Wait() внутри foreach
Добрых времени суток. Есть 2 вложенных foreach'a, внутри последнего необходимо...

Отмена async Task
Хочу: 1) запускать асинхронный метод = ok 2) выводить в textbox процесс...

Запустить метод несколько раз в Task
Имеется консольное приложение в котором пользователь вводит значение переменной...

Task asynk не получается сделать метод фоновым
Мой метод вешает весь ui, хотя делаю все по документации. Что тут не так? ...

Socket.Send + Async & Await: свой асинхронный метод отправки данных
Привет. Хочу написать свой асинх. метод для отправки данных при помощи класса...

11
Psilon
Master of Orion
Эксперт .NET
6012 / 4864 / 902
Регистрация: 10.07.2011
Сообщений: 14,477
Записей в блоге: 5
Завершенные тесты: 4
09.09.2016, 13:30 2
awp-sirius, написана какая-то странная вещь. Попробую предположить, что
а) Load должен быть async Task, а не void.
b) таск должен присваиваться, а не создавать новый:
C#
1
Task task = Load();
0
awp-sirius
58 / 58 / 41
Регистрация: 01.05.2012
Сообщений: 500
09.09.2016, 13:50  [ТС] 3
Psilon, да. первый вариант был именно таким. Но тогда выходит ещё интересней)
Load запускается асинхронно в том же потоке. И начинают выполняться асинхронно.
Когда главный метод доходит до task.Wait() основной поток засыпает и всё. Ничего нигде не происходит.
Load висит в середине на веки вечные...
0
Cupko
459 / 448 / 126
Регистрация: 17.07.2012
Сообщений: 1,329
Записей в блоге: 1
Завершенные тесты: 2
09.09.2016, 14:32 4
Цитата Сообщение от awp-sirius Посмотреть сообщение
Load запускается асинхронно в том же потоке. И начинают выполняться асинхронно.
Когда главный метод доходит до task.Wait() основной поток засыпает и всё. Ничего нигде не происходит.
Load висит в середине на веки вечные...
Потому что вы блокируете своим Task.Wait поток исполнения асинхронного метода. Вам надо решить, асинхронность вам нужна или многопоточность.
Если у вас метод асинхронный, то, как сказали выше он должен возвращать этот таск, и ждать результата нужно await'ом, а не task.Wait()
C#
1
2
Task task = Load();
var result = await task;
0
awp-sirius
58 / 58 / 41
Регистрация: 01.05.2012
Сообщений: 500
09.09.2016, 14:52  [ТС] 5
Cupko, да, это всё понятно. Но мне интересно есть ли какой-нибудь выход в данной ситуации?
В целом конкретно в том месте мне не нужна ни многопоточность, ни асинхронность. Просто в методе Load есть await HttpClient SendAsync...
Потому как HttpWebRequest и прочие содержат внутри лок, который распространяется на вообще всё приложение!!!

Есть ли способ в обычном, синхронном методе подождать пока выполнится асинхронный?
0
Psilon
Master of Orion
Эксперт .NET
6012 / 4864 / 902
Регистрация: 10.07.2011
Сообщений: 14,477
Записей в блоге: 5
Завершенные тесты: 4
09.09.2016, 15:12 6
awp-sirius, в чем проблема написать await и ждать продолжения в том же потоке? Если вам не нужна многопоточность, то это нужное поведение.

Добавлено через 2 минуты
C#
1
2
task.Start();
task.Wait();
Ничем не отличается от того, если бы вы руками просто вызывали синхронный код. Потому что таск, кстати, скорее всего даже будет в том же потоке выполняться: интересная штуковина для этого есть, Task inlining называется.
0
awp-sirius
58 / 58 / 41
Регистрация: 01.05.2012
Сообщений: 500
09.09.2016, 15:52  [ТС] 7
Psilon, Task task = Load(); да, будет в том же потоке, ведь тут просто присвоение.
Не могу написать await Load(), потому как потом придётся тащить async в методах очень глубоко.....
Тем более сейчас это сеттер с override...

Я же переписал архитектуру, всё хорошо, всё работает. Но вопрос остаётся открытым...
Есть ли способ в обычном, синхронном методе подождать пока выполнится асинхронный?
0
Psilon
Master of Orion
Эксперт .NET
6012 / 4864 / 902
Регистрация: 10.07.2011
Сообщений: 14,477
Записей в блоге: 5
Завершенные тесты: 4
09.09.2016, 16:22 8
awp-sirius, ну ждите с помощью Wait. Только вы же ждете не выполнение метода Load, а выполнение запуска этого метода. То есть столько времени, сколько требуется шедулеру чтобы запланировать задачу на выполнение. Так что вы ждете не окончания задачи, а момента, когда задача запланирована (это очень быстрая операция).
0
awp-sirius
58 / 58 / 41
Регистрация: 01.05.2012
Сообщений: 500
09.09.2016, 17:02  [ТС] 9
Psilon, а как ожидать выполнения самой задачи?
я сделал private Task loadTask { get; set; }
В конструкторе loadTask = new Task(Load);

Вот так не ожидает полного выполнения:
C#
1
2
loadTask.Start();
loadTask.Wait();
0
Cupko
459 / 448 / 126
Регистрация: 17.07.2012
Сообщений: 1,329
Записей в блоге: 1
Завершенные тесты: 2
09.09.2016, 22:50 10
awp-sirius, вам нужно в методе Load дождаться await'ом результат и его вернуть. В принципе, выход верный - обернуть асинхронный метод в Task. Почему он у вас не отрабатывает - я не в курсе. Но, думаю, из-за того что нет возврата результата, среда не генерирует код для возврата в вызывающий метод.

Добавлено через 5 минут
awp-sirius, что-то подобное должно отработать:
C#
1
2
3
4
5
var task = Task.Run(() => {
    var x = await SomeAsyncMethod();
    return x;
});
var result = task.Result;

Не по теме:

писал по памяти на коленке, за синтаксис не отвечаю

0
Psilon
Master of Orion
Эксперт .NET
6012 / 4864 / 902
Регистрация: 10.07.2011
Сообщений: 14,477
Записей в блоге: 5
Завершенные тесты: 4
09.09.2016, 23:08 11
awp-sirius, этот код ОЖИДАЕТ окончание выполнения loadTask. Так что весь вопрос в том, как этот loadTask написан.
0
_exp10der_
Warrior
490 / 417 / 177
Регистрация: 23.11.2014
Сообщений: 932
09.09.2016, 23:15 12
В чем профит я непонимаю, окей Task.Run вернул нам сразу управление, но следующей строчкой мы у задачи вызвали блокируйщий метод Result. Что конкретно надо я так и не понял.
0
09.09.2016, 23:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.09.2016, 23:15

Sleep or Wait
Добрый день вот можно сказать начал изучать С# два дня назад и наткнулся на не...

Semaphore Wait(int millisecondsTimeout)
Добрый день. Разбираюсь в многопоточном программировании. Скажите пожалуйста,...

async и try/catch
Добрый день! Писал класс, решил добавить асинхронные методы, проблема в том...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru