Ядро ASP.NET и C#. Как запустить синхронный метод асинхронно

В моем основном приложении ASP.NET используется Entity Framework Core. Как и следовало ожидать, методы контроллера должны быть асинхронными и вызывать асинхронные методы EF Core.

У меня также есть методы контроллера, которые нужно читать и записывать в файлы excel. Я использую OpenXml. Поскольку это операции ввода-вывода, в идеале они должны быть асинхронными, но OpenXml не предлагает никаких асинхронных методов. Вот упрощенный пример

private async Task<model> ReadFromExcel()
{
    using var document = SpreadsheetDocument.Open("filePathAndName", false);

    // read data into model

    document.Close();

    context.Models.Add(newModel);
    await Context.SaveAsync();

    return newModel;
}

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

Directory.EnumerateFiles("excelFolderName", ".xlsx");

Согласно этому документу ASP.NET Core Performance Best Practices я не должен использовать Task.Run, чтобы сделать синхронный API асинхронным. Я понимаю, почему, но применяется ли это правило к операциям ввода-вывода, которые блокируют потенциал потока на несколько секунд? Должен ли я сделать эти операции ввода-вывода асинхронными, и если да, то каков базовый способ сделать чтение и запись файла excel и получить асинхронный список файлов?

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

Patrick Beynio 13.11.2022 18:00

то, что документ пытается вам сказать, это то, что вы не получите выгоды от методов, которые могут быть встроены как await Task.Run(...);, это приведет только к бесполезному планированию.

Patrick Beynio 13.11.2022 18:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
133
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку это операции ввода-вывода, в идеале они должны быть асинхронными, но OpenXml не предлагает никаких асинхронных методов.

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

В идеале это должны быть асинхронные API. Но это не так. Чтобы сделать их асинхронными, нужно исправить API, а не завернуть его в Task.Run. Вы можете отправить запрос сопровождающим OpenXml для асинхронных API. Работа с файловой системой более неудобна; это ограничение Win32, а не ограничение BCL, и вряд ли оно будет исправлено, но вы можете спросить.

применяется ли это правило к операциям ввода-вывода, которые блокируют потенциал потока на несколько секунд?

Да.

Запрос блокируется на одно и то же время, независимо от того, является ли он синхронным или асинхронным. Поэтому нужно учитывать, как блокируются потоки. В идеальном асинхронном случае ни один поток не блокируется. Поскольку у вас есть только синхронные API, вам нужно заблокировать поток; вызов API напрямую заблокирует поток пула потоков, а его отключение в Task.Run заблокирует другой поток пула потоков, что бессмысленно.

Должен ли я сделать эти операции ввода-вывода асинхронными, и если да, то каков базовый способ сделать чтение и запись файла excel и получить асинхронный список файлов?

Вы не можете «сделать их асинхронными». Вы можете запросить асинхронные API, а затем пока использовать синхронные.

Ага. Это то, что я понял, но я должен был спросить.

JHJ 15.11.2022 01:13

Другие вопросы по теме