1
- using System . Collections . Frozen ;
2
- using FluentAssertions ;
1
+ using System . Collections . Frozen ;
2
+ using FluentAssertions ;
3
3
using Microsoft . Extensions . DependencyInjection ;
4
4
using Microsoft . Extensions . Hosting ;
5
5
using Xunit ;
@@ -21,22 +21,57 @@ public async Task Should_RecordCheckpoints()
21
21
await host . StartAsync ( default ) ;
22
22
23
23
var dispatcher = provider . GetRequiredService < IBackgroundTaskDispatcher > ( ) ;
24
- for ( int i = 0 ; i < 20 ; i ++ )
25
- {
24
+ for ( int i = 0 ; i < 20 ; i ++ )
25
+ {
26
26
await dispatcher . DispatchAsync ( ctx => new ValueTask ( Task . Delay ( 200 ) ) , new MyTaskContext ( i ) ) ;
27
27
}
28
28
29
- SpinWait . SpinUntil ( ( ) =>
30
- {
29
+ SpinWait . SpinUntil ( ( ) =>
30
+ {
31
31
var checkpoint = defaultChannel . Checkpoints . Cast < BackgroundTask < MyTaskContext > > ( ) . FirstOrDefault ( ) ;
32
- return checkpoint ? . Context . Id == 19 ;
32
+ return checkpoint ? . Context . Id == 19 ;
33
33
} , 5000 ) . Should ( ) . BeTrue ( ) ;
34
34
35
35
await host . StopAsync ( default ) ;
36
36
var checkpoint = defaultChannel . Checkpoints . Cast < BackgroundTask < MyTaskContext > > ( ) . Single ( ) ;
37
37
checkpoint . Context . Id . Should ( ) . Be ( 19 ) ;
38
38
}
39
39
40
+ [ Fact ]
41
+ public async Task ShouldFinishingInflightTasksBeforeStop ( )
42
+ {
43
+ const int channelCnt = 10 ;
44
+ var services = new ServiceCollection ( ) ;
45
+ services . AddLogging ( ) ;
46
+ services . AddBackgroundTask ( opt=> {
47
+ opt . Channels . Clear ( ) ;
48
+ for ( var i = 0 ; i < channelCnt ; i ++ )
49
+ {
50
+ opt . Channels . Add ( new BackgroundTaskChannelOptions { Key = i . ToString ( ) , Capacity = - 1 } ) ;
51
+ }
52
+ } ) ;
53
+ var provider = services . BuildServiceProvider ( ) ;
54
+
55
+ var host = ( BackgroundTaskHostedService ) provider . GetRequiredService < IHostedService > ( ) ;
56
+ await host . StartAsync ( default ) ;
57
+
58
+ const int taskCnt = 1000 ;
59
+ var processedCnt = 0 ;
60
+ var dispatcher = provider . GetRequiredService < IBackgroundTaskDispatcher > ( ) ;
61
+ for ( int ch = 0 ; ch < channelCnt ; ch ++ )
62
+ {
63
+ for ( int i = 0 ; i < taskCnt ; i ++ )
64
+ {
65
+ await dispatcher . DispatchAsync ( async ctx => {
66
+ await Task . Delay ( 300 * ch ) ;
67
+ Interlocked . Increment ( ref processedCnt ) ;
68
+ } , new MyTaskContext ( i ) , channel : ch . ToString ( ) ) ;
69
+ }
70
+ }
71
+
72
+ await host . StopAsync ( default ) ;
73
+ processedCnt . Should ( ) . Be ( channelCnt * taskCnt ) ;
74
+ }
40
75
}
41
76
42
77
public record MyTaskContext ( int Id ) : IBackgroundTaskContext ;
0 commit comments