亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么調用 IHost.StopAsync 時會調用

為什么調用 IHost.StopAsync 時會調用

C#
蕭十郎 2023-08-20 10:18:49
假設以下使用通用主機的 .NET Core 2.2 控制臺應用程序:using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using System;using System.Threading;using System.Threading.Tasks;namespace SimpleGenericHost{    class SimpleHostedService : IHostedService    {        public Task StartAsync(CancellationToken cancellationToken)        {            Console.WriteLine("Service started");            return Task.CompletedTask;        }        public Task StopAsync(CancellationToken cancellationToken)        {            Console.WriteLine("Service stopped");            return Task.CompletedTask;        }    }    class Program    {        static async Task Main(string[] args)        {            var host = new HostBuilder()                .ConfigureServices(services =>                {                    services.AddHostedService<SimpleHostedService>();                })                .Build();            var runTask = host.RunAsync();            await Task.Delay(5000);            await host.StopAsync();            await runTask;        }    }}當您運行它時,將輸出以下內容:Service startedApplication started. Press Ctrl+C to shut down.Hosting environment: ProductionContent root path: C:\projects\ConsoleApps\SimpleGenericHost\bin\Debug\netcoreapp2.2\Service stoppedService stopped正如你所看到的,SimpleHostedService.StopAsync被調用了兩次。為什么?這是預期的嗎?我錯過了什么嗎?IHostedService.StopAsync還有另一種方法可以停止只被調用一次的主機嗎?
查看完整描述

1 回答

?
嚕嚕噠

TA貢獻1784條經驗 獲得超7個贊

因為它被調用了兩次——一次是在延遲之后,另一次是在服務實際停止時。RunAsync它并不意味著在使用時被調用。


要在超時后停止,請使用帶有超時的 CancellationTokenSource 并將其令牌傳遞給RunAsync:


var timeoutCts=new CancellationTokenSource(5000);


await host.RunAsync(timeoutCts.Token);

解釋


StopAsync 不會停止服務,它用于通知服務需要停止。當應用程序停止時,它由托管服務基礎設施本身調用。


.NET Core 是開源的,這意味著您可以檢查RunAsync 源。RunAsync啟動主機,然后等待終止:


await host.StartAsync(token);


await host.WaitForShutdownAsync(token);

WaitForShutdownAsync方法偵聽來自控制臺或通過顯式調用的終止請求IHostApplicationLifetime.StopApplication。當這種情況發生時,它會調用StopAsync自己:


await waitForStop.Task;


// Host will use its default ShutdownTimeout if none is specified.

await host.StopAsync();

如果您打算自己管理應用程序的生命周期,則應該使用StartAsync而不是。RunAsync


但在這種情況下,您只需在超時時停止應用程序。您可以通過CancellationTokenSource(int)構造函數將取消令牌傳遞給RunAsync僅在超時后觸發的取消令牌,從而輕松地做到這一點:


var timeoutCts=new CancellationTokenSource(5000);


await host.RunAsync(timeoutCts.Token);


查看完整回答
反對 回復 2023-08-20
  • 1 回答
  • 0 關注
  • 150 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號