我發現了很多類似的帖子,但沒有一個專門概述我遇到的問題。
我有一個 C# Worker 專案。在StartAsyncworker的方法中,我呼叫await TryConnect();
TryConnect看起來是這樣的:
private async Task TryConnect()
{
Logging.Log("1");
var startResult = await StartUserStreamAsync();
Logging.Log("2");
if (!startResult.Success)
{
Logging.Log("3");
throw new Exception($"Failed to start: {startResult.Error}");
}
listenKey = startResult.Data;
Logging.Log("4");
}
呼叫站點如下所示:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
//initialize
await Initialize();
///other code
}
private async Task InitializeBinance()
{
///other code
await TryConnect();
///other code
}
你可能猜到了。1、2 和 3,登錄控制臺。但是, 4 不是,并且拋出例外。
在以前的正常完全同步控制臺應用程式中。這只是拋出一個未捕獲的例外,應用程式停止執行,一切都如我所料。我不打算從那種狀態中恢復過來。然而在異步領域,它保持沉默。沒有拋出例外,除了呼叫方法的執行似乎停止外,沒有任何跡象表明有任何問題。
為什么會這樣,我該怎么辦?我是否被迫嘗試/抓住它,如果是這樣,如果你忘記了怎么辦?你只是想弄清楚你不那么明顯的錯誤嗎?
uj5u.com熱心網友回復:
您發布的代碼的異步方面是正確的并且按預期作業。
但是,由于您使用的是 Worker,因此來自其他應用程式型別的假設不成立。
由于 worker 是通過 a 實作的BackgroundService,因此該ExecuteAsync方法僅在同步拋出時才會導致失敗。這被解釋為服務啟動期間的錯誤。
一旦ExecuteAsync掛起(遇到第一個執行實際異步作業的等待),則BackgroundService假定正常的服務作業現在正在進行中并且它已成功啟動。之后,假定該服務正在運行。
一旦服務關閉(例如通過在服務管理器中停止sudo systemctl stop等),它將觸發傳遞給的取消令牌ExecuteAsync并等待回傳的Task. 此時,它會遇到您期望的例外。
我的理解是服務不應該需要用戶互動,他們應該繼續做他們所做的一切,對他們程序中任何可能的錯誤有彈性,向相應的作業系統設施(例如事件日志)報告任何錯誤。因此,任何已完成的代碼ExecuteAsync都應包含在適當的 try/catch 中,可能除了OperationCanceledException在關閉時從取消令牌中拋出的代碼。
如果在某個時候,您意識到該服務無法再運行,您可以通過IHostApplicationLifetime.StopApplication( doc )終止托管行程
如果您在啟動期間需要異步作業,可以IHostedService直接實作您的作業程式并實作StartAsync您認為合適的方法。
另請參閱GitHub 上的 BackgroundService 源以供參考。Microsoft Docs 也有實作 IHostedService 介面教程。
我還可以建議閱讀.NET Generic Host,因為這是管理 worker 的底層基礎設施BackgroundService。關于主機生命周期和相關概念的內容相當多。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/419182.html
標籤:
上一篇:XML反序列化C#
