[英]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.