AS PNet Entity Framework 6 - EF6, смешивающий asyn c и syn c в одной единице работы - PullRequest
3 голосов
/ 27 января 2020

Сегодня я натолкнулся на несколько строк кода, которые, в развернутом виде, составляют что-то вроде этого:

using (var db = new AppDbContext())
{
    var foo = await db.Foos
        .Where(m => m.Name == "BuzzBaz" )
        .FirstAsync();

    foo.Name = "Quxx";
    db.SaveChanges();
}

Обратите внимание, что запросом выбора является async, но вызов SaveChanges () - нет. Это синхронно!

Может ли это создать проблемы? Должен ли я просто рефакторинг это использовать db.SaveChangesAsync(); и все хорошо? Или, может быть, просто позвоните First() вместо FirstAsync()? Или, может быть, это безвредно и может иметь некоторую выгоду для общей производительности системы?

Я нашел некоторую документацию, которая заставляет меня думать, что удаление async в целом, вероятно, является хорошим выбором здесь. https://docs.microsoft.com/en-us/ef/ef6/fundamentals/async

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

Ответы [ 2 ]

1 голос
/ 27 января 2020

Помимо согласованности кодирования, что очень важно, рассмотрим следующее:

  1. Это библиотека DAL? Вы уверены, кто будет его использовать, и уверены, что повторное использование кода никогда не будет проблемой?

Если ответ таков, придерживайтесь asyn c использования. Пользовательский интерфейс внешнего интерфейса будет заблокирован во время сохранения, что делает его не реагирующим. Веб-API используют потоки ввода-вывода, которые обеспечивают лучшее управление потоками: Простое описание рабочих потоков и потоков ввода-вывода. NET

Если это библиотека, обязательно используйте ConfigureAwait(false) для всех вызовов функции asyn c.

Даже при использовании await вызов асинхронный, с точки зрения протирки, выполняемой в другом потоке, в то время как оригинал ожидает. В большинстве случаев это незначительно с точки зрения производительности, но почему бы и нет?

Я обычно делаю все асинхронно c, и, если это необходимо для реализации syn c, я предпочитаю делать дубликаты кода с syn c версия.

1 голос
/ 27 января 2020

Ваш код как «правильный», то есть он не имеет фундаментального недостатка.

Давайте проанализируем, что происходит, и мои 2 цента на них:

  • При выполнении запроса к БД (FirstAsync) использование await означает, что инструкции будут выполняться последовательно, но поток не будет заблокирован (асинхронный вызов) и может использоваться для других целей. Вероятно, это хорошая вещь, если это серверное приложение, вы можете захотеть, чтобы ваши потоки могли обрабатывать другие запросы в ожидании ответа БД.

  • Использование non-asyn c SaveChanges однако заблокирует поток. Само по себе это не ошибка, но, поскольку это также операция ввода-вывода в БД, он может блокировать поток на некоторое значительное время. Действительно, это выглядело бы более «последовательным», если бы вы также await имели здесь также версию asyn c.

Это проблема? Это зависит. Ваше приложение интенсивно используется? Ваши пользователи испытывают низкую реактивность при большой нагрузке? Тогда в этом случае может быть потенциальным улучшением использование asyn c при сохранении.

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

Сочетание употреблений само по себе не является проблемой.

Лично я бы go предложил бы также асин c SaveChanges, для согласованности и воображения, что Запись в БД - это некоторая операция ввода-вывода, которая может быть медленной.

Если это настольное приложение, просто убедитесь, что вы не блокируете поток пользовательского интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...