簡體   English   中英

從同步方法調用異步方法是 ASP .NET web api - 問題

[英]Calling async method from sync method is ASP .NET web api - issue

我有一個 ASP .NET web api 2 應用程序,我試圖從同步方法調用 asnyc 方法,同時我遇到了一些問題。 如果我只是將該方法作為常規方法調用,則延遲后的主體不會被執行,如果我用 Task.Run() 調用它,它會被執行

public void CallingMethod(MethodExecutionArgs args)
{
  //do something with the args
            System.Diagnostics.Debug.WriteLine("BEFORE ");

            WriteFileToDiskAsync(args); // If I run only this, I never see "WriteFile() - AFTER delay" in the output
            Task.Run(async () => await WriteFileToDiskAsync(args)); // this executes the entire async method
            System.Diagnostics.Debug.WriteLine($"Finally written from sync method");

}

private async Task<bool> WriteFileToDiskAsync(dynamic file)
{
            System.Diagnostics.Debug.WriteLine("Before delay inside async");
            await Task.Delay(3000);
            System.Diagnostics.Debug.WriteLine("WriteFile() - AFTER delay");
}

結果:我總是看到從CallingMethod寫的行,但是當我像常規方法一樣調用異步方法時,我只看到“在異步內部延遲之前” ,如果我用 Task.Run() 調用它,它會看到來自異步方法。

問題 1:有人可以解釋這種行為,為什么 async 方法沒有完全執行? 這是否與 Stephen Cleary 所說的有關:如果您因任何原因丟失了 AppDomain,那么正在進行的工作就會丟失。

我閱讀了這些文章,但無法弄清楚為什么會發生這種情況:

上下文:我想要實現的是,在創建X Resource (將其保存在數據庫中)的現有 API 路由上,在創建X Resource后,我想異步調用一個方法,該方法將創建一個 json 文件來自該 X 資源的一些信息並將其保存在文件系統中。 但即使文件寫入失敗,我也想向客戶端返回一個成功的響應(因為他的請求是實際保存X Resource - 成功了)他並不關心在 XYZ 文件系統中創建外部文件。

問題 2:考慮到 CreateResource 路由中鏈接的所有現有方法都是同步的,您認為實現上述目標的最佳實踐是什么?

問題 1:有人可以解釋這種行為,為什么 async 方法沒有完全執行? 這是否與 Stephen Cleary 所說的有關:如果您因任何原因丟失了 AppDomain,那么正在進行的工作就會丟失。

不。在這種情況下,AppDomain 仍然存在。 在 ASP.NET(pre-Core)中,有一個代表請求的 ASP.NET SynchronizationContext 默認情況下await捕獲當前上下文並使用它來恢復執行其async方法

因此,當await完成時,它會嘗試繼續在SynchronizationContext上為該請求執行。 但是,該請求已完成,因此在該上下文中恢復沒有意義。 由此產生的行為是未定義的。

問題 2:考慮到 CreateResource 路由中鏈接的所有現有方法都是同步的,您認為實現上述目標的最佳實踐是什么?

如果您確定要提前返回,那么您應該有一個后台服務句柄來創建文件,而不是 ASP.NET 服務。 由於您已經擁有一個數據庫,因此您可以使用發件箱模式,將消息放在“發件箱”表中,作為與您的資源創建相同的事務的一部分。 然后一個單獨的后台服務讀取“發件箱”表並寫入 JSON 文件。

暫無
暫無

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

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