Подтвердить что ты не робот

Как ждать работы async в С#

Я пытаюсь понять, как ждать работы async на С#, и одна вещь меня пугает. Я понимаю, что любой метод, использующий ключевое слово await, должен быть помечен async. Я понимаю, что когда строка с ключевым словом await попадает в код ниже, эта строка не выполняется. Операция async запускается для выполнения оператора в строке ожидания и элемент управления возвращается вызывающему методу, который может продолжить выполнение.

Вопрос № 1: Правильно ли это предположение или код ниже ключевого слова await все еще выполняется?

Во-вторых, предположим, что я вызвал метод async службы и должен вернуть его результат. Оператор return находится ниже ключевого слова ожидания.

Вопрос №2: Когда появляется ответ return, после завершения асинхронного вызова или до него?

Вопрос № 3: Я хочу использовать результат этого вызова службы, и операция async не поможет, потому что я хочу, чтобы вызывающий метод попадал, когда результат был возвращен. Я понимаю, что это можно сделать, используя свойство Result, которое вызывает синдром вызова. Но тогда использование асинхронных операций в DB приводит к тому, что они фактически занимают 80% времени в большинстве приложений.

Вопрос № 4: Как я могу использовать асинхронные операции с БД? Возможно ли и рекомендовано?

Вопрос № 5: В каких сценариях будут использоваться операции async, кажется, что каждый api просто делает асинхронные операции без причины? или мне не хватало смысла использовать async ops?

Что я имею в виду, говоря, что api делает asyn-методы без причины, потому что методы должны что-то возвращать и до тех пор, пока не будут сделаны эти вычисления, как они могут вернуться так, в сущности не будет ли этот вызов блокироваться в том смысле, что он будет быть бесполезным до тех пор, пока результат не будет возвращен?

4b9b3361

Ответ 1

MSDN объясняет все.

Я понимаю, что иногда ванильные документы (особенно из MSDN) могут быть трудно применимы к вашей конкретной ситуации, поэтому отпустите свои очки.

Вопрос № 1: Правильно ли это предположение или код ниже ключевого слова await все еще выполняется?

Код ниже ключевого слова "ожидание" будет выполняться только после завершения асинхронного вызова. Тем временем, поскольку ваш метод помечен как "асинхронный", управление будет возвращено вызывающей стороне вашего метода до тех пор, пока ваш метод не завершится. Из ссылки MSDN выше:

Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();

// The await operator suspends AccessTheWebAsync. 
//  - AccessTheWebAsync can't continue until getStringTask is complete. 
//  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
//  - Control resumes here when getStringTask is complete.  
//  - The await operator then retrieves the string result from getStringTask. 
string urlContents = await getStringTask;

Я думаю, что комментарии вполне объяснительны.

Во-вторых, предположим, что я вызвал метод async службы и должен вернуть его результат. Оператор return находится ниже ключевого слова ожидания.

Вопрос №2: Когда появляется ответ return, после завершения асинхронного вызова или до него?

После.

Вопрос № 3: Я хочу использовать результат этого вызова службы, и операция async не поможет, потому что я хочу, чтобы вызывающий метод попадал, когда результат был возвращен. Я понимаю, что это можно сделать, используя свойство Result, которое вызывает синдром вызова. Но тогда использование асинхронных операций в DB приводит к тому, что они фактически занимают 80% времени в большинстве приложений.

Предположим, вам нужно сделать три несвязанных запроса БД, чтобы завершить вашу службу, затем выполнить расчет на основе результатов, а затем закончить. Если вы сделаете это последовательно, вам придется подождать, пока не завершится каждая операция. Если вы используете асинхронные вызовы, С# будет запускать три запроса параллельно, и ваш сервис может закончиться намного раньше.

Кроме того, операции, возвращающие задачу, могут использоваться как фьючерсы. См. MSDN on Futures, где обсуждается несколько шаблонов о том, как распараллелить работу на основе фьючерсов и объединить результаты.

Если вашему сервису нужен только один вызов БД, то, безусловно, будет хуже для вас назвать его асинхронным.

Вопрос № 4: Как я могу использовать асинхронные операции с БД? Возможно ли и рекомендовано?

В ADO.NET теперь включены методы async ReadAsync и NextResultAsync.

Это определенно возможно, так как для рекомендованных это обсуждение намного более полно, чем я мог бы написать здесь.

Вопрос № 5: В каких сценариях будут использоваться операции async, кажется, что каждый api просто делает асинхронные операции без причины? или мне не хватало смысла использовать async ops?

Операции async

очень полезны, чтобы легко распараллелить любые длительные операции без проблем с потоками. Если ваш метод делает только одно, или последовательность простых (быстрых) вещей, то да, бесполезно идти асинхронно. Однако, если у вас есть несколько более длинных операций, гораздо проще и меньше подверженности ошибкам распараллеливать их с помощью async, чем для управления потоками.

Ответ 2

На большинство ваших вопросов отвечает официальный документация, а также в вступительном сообщении, которое я написал.

Вопрос № 4: Как я могу использовать асинхронные операции с БД? Возможно ли это,

Entity Framework 6 (в настоящее время в бета-версии) поддерживает async. API-интерфейсы базы данных нижнего уровня поддерживают асинхронные операции так или иначе. Некоторые из них (например, SQLite) поддерживают async напрямую; другим вам нужно написать простые async -совместимые обертки.

... и рекомендуется?

Да, если вы не пишете внешний сервер (например, ASP.NET), который разговаривает с немасштабируемой машиной с одной базой данных на задней панели. В этом конкретном случае нет смысла делать ваш передний фронт, потому что ваш задний конец не может масштабироваться, чтобы соответствовать ему в любом случае.

Вопрос № 5: В каких сценариях будут использоваться операции async, кажется, что каждый api просто делает асинхронные операции без причины? или мне не хватало смысла использовать async ops?

Преимущества асинхронных операций:

  • На стороне клиента (UI) ваше приложение остается отзывчивым.
  • На стороне сервера ваше приложение масштабируется лучше.