В моем основном приложении 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 и получить асинхронный список файлов?
то, что документ пытается вам сказать, это то, что вы не получите выгоды от методов, которые могут быть встроены как await Task.Run(...);
, это приведет только к бесполезному планированию.
Поскольку это операции ввода-вывода, в идеале они должны быть асинхронными, но OpenXml не предлагает никаких асинхронных методов.
Кроме того, мне нужно сначала найти файл в папке, которую я также хотел бы сделать асинхронной.
В идеале это должны быть асинхронные API. Но это не так. Чтобы сделать их асинхронными, нужно исправить API, а не завернуть его в Task.Run
. Вы можете отправить запрос сопровождающим OpenXml для асинхронных API. Работа с файловой системой более неудобна; это ограничение Win32, а не ограничение BCL, и вряд ли оно будет исправлено, но вы можете спросить.
применяется ли это правило к операциям ввода-вывода, которые блокируют потенциал потока на несколько секунд?
Да.
Запрос блокируется на одно и то же время, независимо от того, является ли он синхронным или асинхронным. Поэтому нужно учитывать, как блокируются потоки. В идеальном асинхронном случае ни один поток не блокируется. Поскольку у вас есть только синхронные API, вам нужно заблокировать поток; вызов API напрямую заблокирует поток пула потоков, а его отключение в Task.Run
заблокирует другой поток пула потоков, что бессмысленно.
Должен ли я сделать эти операции ввода-вывода асинхронными, и если да, то каков базовый способ сделать чтение и запись файла excel и получить асинхронный список файлов?
Вы не можете «сделать их асинхронными». Вы можете запросить асинхронные API, а затем пока использовать синхронные.
Ага. Это то, что я понял, но я должен был спросить.
ASP не выполняет действия в потоке пользовательского интерфейса, и похоже, что вам нужно делать что-то по порядку, поэтому я думаю, вам следует послушать тамошнюю документацию...