簡體   English   中英

ASP.NET core & C#. 如何異步運行同步方法

[英]ASP.NET core & C#. How to run a synchronous method asynchronously

我的 ASP.NET 核心應用程序使用 Entity Framework Core。 正如您所期望的那樣,controller 方法必須是異步的並調用 EF Core 的異步方法。

我還有 controller 個方法需要讀取和寫入 excel 個文件。 我正在使用 OpenXml。 由於這些是 IO 操作,理想情況下它們將是異步操作,但 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 異步。 我明白為什么,但該規則是否適用於 IO 操作,這將阻塞線程潛力幾秒鍾? 我應該使這些 IO 操作異步嗎?如果是這樣,使讀寫 excel 文件和獲取文件列表異步的基本方法是什么?

由於這些是 IO 操作,理想情況下它們將是異步操作,但 OpenXml 不提供任何異步方法。

另外,我需要先在一個文件夾中找到該文件,我也想將其設為異步。

理想情況下,這些將是異步 API。 但他們不是。 使它們異步的方法是修復 API,而不是將其包裝在Task.Run中。 您可以向 OpenXml 的維護者提出請求以獲取異步 API。 文件系統操作比較笨拙; 這是 Win32 限制,而不是 BCL 限制,不太可能修復,但您可以詢問。

該規則是否適用於 IO 操作,這將阻塞線程潛力幾秒鍾?

是的。

無論請求是同步的還是異步的,請求都會被阻塞相同的時間。 所以要考慮的是線程是如何被阻塞的。 在理想的異步情況下,沒有線程被阻塞。 由於您只有同步 API,因此您必須阻塞一個線程; 直接調用 API 將阻塞一個線程池線程,並將其推到Task.Run將阻塞另一個線程池線程——這是沒有意義的。

我應該使這些 IO 操作異步嗎?如果是這樣,使讀寫 excel 文件和獲取文件列表異步的基本方法是什么?

你不能“讓他們異步”。 您可以請求異步 API,然后暫時使用同步 API。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM