. NET Core EF, когда следует избегать асинхронных вызовов базы данных - PullRequest
1 голос
/ 23 февраля 2020

В настоящее время я пишу простое веб-приложение, которое использует базу данных ms sql для хранения данных. Сейчас я пытаюсь настроить свой уровень бизнес-логики c и, таким образом, структурировать его наилучшим образом.

В настоящее время все мои вызовы выполняются с помощью Linq, и на самом деле ни один из них не является асинхронным , Я довольно новичок в асинхронном программировании и, как правило, любопытно узнать, для каких запросов мне следует использовать асинхронные вызовы.

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

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

Наконец, из того, что я прочитал и увидел, многие люди предпочитают использовать асинхронные вызовы базы данных. То есть скорее правило, чем исключение.

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

1 Ответ

0 голосов
/ 23 февраля 2020

Asyn c в MVC - это освобождение потоков обработки запросов, чтобы они могли отвечать на дополнительные запросы. Это не делает код быстрее, а делает его немного медленнее. Когда дело доходит до потоков, довольно легко увидеть, что он делает, когда он передается рабочему потоку. Что произойдет после завершения этого метода asyn c, зависит от контекста синхронизации. В большинстве случаев оно возобновляется в рабочем потоке.

Поэтому использование префиксов [thread #]:

[1] using(var context = new AppContext())
    {
[1]     var orders = await context.Orders
            .Where(x => x.CustomerId == customerId)
            .OrderBy(x => x.OrderDate)
            .ToListAsync();
[2]     foreach(var order in orders)
        {
            //...
        }
    }

await / async означает, что C# будет передан рабочий поток для выполнения кода, в данном случае в EF для запроса заказов. Он создает точку возобновления для оставшегося кода, который будет выполнен после завершения этой операции. Тем временем поток № 1 завершает работу и MVC может использовать его для ответа на другие запросы.

При рассмотрении асинхронных вызовов следует учитывать время, необходимое для выполнения операции, и время / ресурсы, необходимые для создания пути возобновления и код возобновления. Асинхронные вызовы наиболее полезны, когда сталкиваются с относительно нечасто большими, дорогостоящими операциями, которые могут привести к увеличению потоков ответов, которые в противном случае могли бы обслуживать запросы в ожидании отправителя. Для быстрых общих операций async может замедлить процесс. Так что, как правило, если для выполнения операции требуется больше одной или двух секунд, она хорошо подходит для async / await. Для быстрых запросов я оставляю их синхронными по умолчанию.

...