Как далеко пробрасывать async\await
От: mr Pink  
Дата: 23.07.15 09:06
Оценка:
Добрый день.

Вроде понятно для чего использовать async\await, но все примеры и всегда ограничены одним методом одного класса, а как быть:
1. с более вложенной структурой.

public static Main(){
    var a=(new A()).get();
}

class A{
    public void get(){
        //как запускать b.getAsync()?
    }
}


В этом случае делать в классе A метод Task getAsync() ? Или как-то получить результат из асинхронной b.getAsync()?
В общем случае, где и как заканчивать асинхронные вызовы? Или тащить до Main?

2. Есть сласс с методом CreateRecord, в котором нужно эту созданную запись в том числе сохранить в БД, отправить в очередь и положить, например, в файл.
Вопрос: если все три метода асинхронные, то как правильно делать их вызов? Если просто
await methodDBAsync();
await methodMQAsync();
await methodFileAsync();

то все три метода пойдут синхронно, каждый раз возвращая управление методу выше. Я прав?
Re: Как далеко пробрасывать async\await
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.07.15 10:03
Оценка:
Здравствуйте, mr Pink, Вы писали:

MP>Добрый день.


MP>Вроде понятно для чего использовать async\await, но все примеры и всегда ограничены одним методом одного класса, а как быть:

MP>1. с более вложенной структурой.

MP>В этом случае делать в классе A метод Task getAsync() ? Или как-то получить результат из асинхронной b.getAsync()?

MP>В общем случае, где и как заканчивать асинхронные вызовы? Или тащить до Main?
Раз вам понятно, для чего использовать async\await, то расскажите, пожалуйста, для чего вы их хотите использовать в Main?

MP>Вопрос: если все три метода асинхронные, то как правильно делать их вызов? Если просто

MP>
MP>await methodDBAsync();
MP>await methodMQAsync();
MP>await methodFileAsync();
MP>

MP>то все три метода пойдут синхронно, каждый раз возвращая управление методу выше. Я прав?
Что вы подразумеваете здесь под "пойдут синхронно"?
Re[2]: Как далеко пробрасывать async\await
От: mr Pink  
Дата: 23.07.15 10:17
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, mr Pink, Вы писали:


MP>>Добрый день.


MP>>Вроде понятно для чего использовать async\await, но все примеры и всегда ограничены одним методом одного класса, а как быть:

MP>>1. с более вложенной структурой.

MP>>В этом случае делать в классе A метод Task getAsync() ? Или как-то получить результат из асинхронной b.getAsync()?

MP>>В общем случае, где и как заканчивать асинхронные вызовы? Или тащить до Main?
S>Раз вам понятно, для чего использовать async\await, то расскажите, пожалуйста, для чего вы их хотите использовать в Main?

Хорошо, раз вы так формулируете вопрос, то объясните неучу, как запускать асинхронный I/O-bound метод, например, доступа к БД? Ведь для этого асинхронные методы нужны прежде всего. Просто Task.Run()?

MP>>Вопрос: если все три метода асинхронные, то как правильно делать их вызов? Если просто

MP>>
MP>>await methodDBAsync();
MP>>await methodMQAsync();
MP>>await methodFileAsync();
MP>>

MP>>то все три метода пойдут синхронно, каждый раз возвращая управление методу выше. Я прав?
S>Что вы подразумеваете здесь под "пойдут синхронно"?

Я так понимаю, при вызове этого кода на каждом await управление будет возвращаться в точку вызова всего метода, а после получения результата — продолжать выполнение?
Re[3]: Как далеко пробрасывать async\await
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.07.15 11:04
Оценка:
Здравствуйте, mr Pink, Вы писали:

MP>Здравствуйте, samius, Вы писали:


S>>Раз вам понятно, для чего использовать async\await, то расскажите, пожалуйста, для чего вы их хотите использовать в Main?


MP>Хорошо, раз вы так формулируете вопрос, то объясните неучу, как запускать асинхронный I/O-bound метод, например, доступа к БД? Ведь для этого асинхронные методы нужны прежде всего. Просто Task.Run()?


Вопрос же не в том, КАК, а вопрос в том, ДЛЯ ЧЕГО/зачем?
На вопрос КАК (из Main) ответить легко. Task.Run(...).Wait() + откатчить AggregateException.

На мой взгляд, асинхронные методы нужны не для того, что бы их запускать, а для определенных сценариев. И вызов из Main — не тот сценарий, для которого они предназначены.

MP>>>то все три метода пойдут синхронно, каждый раз возвращая управление методу выше. Я прав?

S>>Что вы подразумеваете здесь под "пойдут синхронно"?

MP>Я так понимаю, при вызове этого кода на каждом await управление будет возвращаться в точку вызова всего метода, а после получения результата — продолжать выполнение?

Верно. Но я бы не стал называть это "синхронно". Все-таки последовательно, цепочка ведь.
Re[4]: Как далеко пробрасывать async\await
От: mr Pink  
Дата: 23.07.15 11:50
Оценка:
S>Верно. Но я бы не стал называть это "синхронно". Все-таки последовательно, цепочка ведь.
Ну тут просто как противоположность "асинхронному", а если последовательно, то наоборот — параллельно.

К вопросу "зачем":
как я понял, await methodAsync() выполняется в том же потоке, отложенно, а Task.Run() дёргает ThreadPool для выделения нового потока...

Пока писал ответ понял, что не так формулирую. Мне нужно "дёрнуть" асинхронные вызовы (все три) без выделения новых потоков. И продолжить работу.
Но! Мне важен результат выполнения.
Re[5]: Как далеко пробрасывать async\await
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.07.15 12:12
Оценка: +1
Здравствуйте, mr Pink, Вы писали:


S>>Верно. Но я бы не стал называть это "синхронно". Все-таки последовательно, цепочка ведь.

MP>Ну тут просто как противоположность "асинхронному", а если последовательно, то наоборот — параллельно.

MP>К вопросу "зачем":

MP>как я понял, await methodAsync() выполняется в том же потоке, отложенно,
Тут не все так просто. Начинается выполнение в том же потоке, но за разрывом выполнения дальше не факт, что в том же. Т.е. слева справа от await начинает работу тот же поток, потом внутри может быть разрыв выполнения, а слева от await можем получить другой поток. Но тоже не факт. Можем другой, а можем тот же. Зависит от обстоятельств.

MP>а Task.Run() дёргает ThreadPool для выделения нового потока...

Не обязательно нового. Просто другого. В этом случае выполнение пойдет "параллельно" с текущим потокм.

MP>Пока писал ответ понял, что не так формулирую. Мне нужно "дёрнуть" асинхронные вызовы (все три) без выделения новых потоков. И продолжить работу.

MP>Но! Мне важен результат выполнения.
Возможность этого зависит от того, как написаны те три метода. Если у них стоит просто return Task.FromResult(1); то можно быть уверенным что выполнение их закончится в том же потоке, что и началось. А если у них стоят разрывы выполнения, то может произойти переключение.
В общем, если вы запустите эти три метода в параллельном потоке и вызовете ожидание (Task.Run(...).Result), то результат вы получите в текущем потоке. Но для выполнения этих методов будет выделен как минимум один левый поток.
Отредактировано 23.07.2015 13:18 samius . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.