Skip to content

Commit ceda38a

Browse files
committed
Enhance HostApplicationLifetime and add logging
- Added `using` directive for `TelegramBot.Services` in `BotApp.cs`. - Retrieve `HostApplicationLifetime` using `GetRequiredService<HostApplicationLifetime>()`. - Added logging for hosted services start and stop events. - `ApplicationStopping` event now triggers logging and cancels `_cancellationTokenSource`. - Added `NotifyStarted`, `NotifyStopping`, and `NotifyStopped` methods to manage lifecycle events. - Implemented `IDisposable` in `HostApplicationLifetime` to manage three `CancellationTokenSource` instances. - `StopApplication` method now cancels all three `CancellationTokenSource` instances. - `Dispose` method now disposes of the three `CancellationTokenSource` instances.
1 parent dd63c20 commit ceda38a

2 files changed

Lines changed: 50 additions & 12 deletions

File tree

Sources/TelegramBot/BotApp.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using Microsoft.Extensions.Hosting;
1616
using Newtonsoft.Json.Linq;
1717
using TelegramBot.Attributes;
18+
using TelegramBot.Services;
1819

1920
namespace TelegramBot
2021
{
@@ -117,10 +118,23 @@ public async Task StartAsync(CancellationToken cancellationToken = default)
117118
throw ex;
118119
}
119120
var hostedServices = _serviceProvider.GetServices<IHostedService>();
121+
var hostApplicationLifetime = _serviceProvider.GetRequiredService<HostApplicationLifetime>();
120122
foreach (var hostedService in hostedServices)
121123
{
122124
await hostedService.StartAsync(mergedToken);
125+
_logger.LogInformation("Started '{hostedService}'.", hostedService.GetType().Name);
126+
hostApplicationLifetime.ApplicationStopping.Register(() =>
127+
{
128+
_logger.LogInformation("Stopping '{hostedService}'...", hostedService.GetType().Name);
129+
hostedService.StopAsync(mergedToken).Wait();
130+
});
123131
}
132+
hostApplicationLifetime.ApplicationStopping.Register(() =>
133+
{
134+
_logger.LogInformation("Application stopping event received.");
135+
_cancellationTokenSource.Cancel();
136+
});
137+
hostApplicationLifetime.NotifyStarted();
124138
}
125139

126140
private void OnProcessExit(object sender, EventArgs e)
@@ -138,8 +152,8 @@ public async Task StopAsync(CancellationToken cancellationToken = default)
138152
{
139153
CheckDisposed();
140154
_logger.LogInformation("Stopping hosted services...");
141-
var hostApplicationLifetime = _serviceProvider.GetRequiredService<IHostApplicationLifetime>();
142-
hostApplicationLifetime.StopApplication();
155+
var hostApplicationLifetime = _serviceProvider.GetRequiredService<HostApplicationLifetime>();
156+
hostApplicationLifetime.NotifyStopping();
143157
var hostedServices = _serviceProvider.GetServices<IHostedService>();
144158
List<Task> tasks = new List<Task>();
145159
foreach (var hostedService in hostedServices)
@@ -158,6 +172,8 @@ public async Task StopAsync(CancellationToken cancellationToken = default)
158172
_logger.LogInformation("Stopping bot updates...");
159173
_cancellationTokenSource.Cancel();
160174
await Task.WhenAll(tasks);
175+
hostApplicationLifetime.NotifyStopped();
176+
hostApplicationLifetime.StopApplication();
161177
}
162178

163179
/// <summary>
Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,48 @@
1-
using System.Threading;
1+
using System;
2+
using System.Threading;
23
using Microsoft.Extensions.Hosting;
34

45
namespace TelegramBot.Services
56
{
6-
internal class HostApplicationLifetime : IHostApplicationLifetime
7+
internal class HostApplicationLifetime : IHostApplicationLifetime, IDisposable
78
{
8-
private readonly CancellationTokenSource _cancellationTokenSource;
9+
private readonly CancellationTokenSource stopTokenSource = new CancellationTokenSource();
10+
private readonly CancellationTokenSource stoppingTokenSource = new CancellationTokenSource();
11+
private readonly CancellationTokenSource startTokenSource = new CancellationTokenSource();
912

10-
public HostApplicationLifetime(CancellationTokenSource cancellationTokenSource)
13+
public CancellationToken ApplicationStarted => startTokenSource.Token;
14+
15+
public CancellationToken ApplicationStopping => stoppingTokenSource.Token;
16+
17+
public CancellationToken ApplicationStopped => stopTokenSource.Token;
18+
19+
public void StopApplication()
1120
{
12-
_cancellationTokenSource = cancellationTokenSource ?? throw new System.ArgumentNullException(nameof(cancellationTokenSource));
21+
stopTokenSource.Cancel();
22+
stoppingTokenSource.Cancel();
23+
startTokenSource.Cancel();
1324
}
1425

15-
public CancellationToken ApplicationStarted => _cancellationTokenSource.Token;
26+
public void NotifyStarted()
27+
{
28+
startTokenSource.Cancel();
29+
}
1630

17-
public CancellationToken ApplicationStopping => _cancellationTokenSource.Token;
31+
public void NotifyStopped()
32+
{
33+
stopTokenSource.Cancel();
34+
}
1835

19-
public CancellationToken ApplicationStopped => _cancellationTokenSource.Token;
36+
public void NotifyStopping()
37+
{
38+
stoppingTokenSource.Cancel();
39+
}
2040

21-
public void StopApplication()
41+
public void Dispose()
2242
{
23-
_cancellationTokenSource.Cancel();
43+
stopTokenSource.Dispose();
44+
stoppingTokenSource.Dispose();
45+
startTokenSource.Dispose();
2446
}
2547
}
2648
}

0 commit comments

Comments
 (0)