1+ // Copyright (c) Microsoft. All rights reserved.
2+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+ namespace DotNetty . Codecs
5+ {
6+ using System ;
7+ using System . Threading . Tasks ;
8+ using DotNetty . Common . Utilities ;
9+ using DotNetty . Transport . Channels ;
10+
11+ public static class TaskExtensions
12+ {
13+ public static async Task CloseOnComplete ( this ValueTask task , IChannelHandlerContext ctx )
14+ {
15+ try
16+ {
17+ await task ;
18+ }
19+ finally
20+ {
21+ await ctx . CloseAsync ( ) ;
22+ }
23+ }
24+
25+ static readonly Func < Task , object , Task > CloseOnCompleteContinuation = Close ;
26+ static readonly Func < Task , object , Task > CloseOnFailureContinuation = CloseOnFailure ;
27+
28+ public static Task CloseOnComplete ( this Task task , IChannelHandlerContext ctx )
29+ => task . ContinueWith ( CloseOnCompleteContinuation , ctx , TaskContinuationOptions . ExecuteSynchronously ) ;
30+
31+ public static Task CloseOnComplete ( this Task task , IChannel channel )
32+ => task . ContinueWith ( CloseOnCompleteContinuation , channel , TaskContinuationOptions . ExecuteSynchronously ) ;
33+
34+ public static Task CloseOnFailure ( this Task task , IChannelHandlerContext ctx )
35+ => task . ContinueWith ( CloseOnFailureContinuation , ctx , TaskContinuationOptions . ExecuteSynchronously ) ;
36+
37+ static Task Close ( Task task , object state )
38+ {
39+ switch ( state )
40+ {
41+ case IChannelHandlerContext ctx :
42+ return ctx . CloseAsync ( ) ;
43+ case IChannel ch :
44+ return ch . CloseAsync ( ) ;
45+ default :
46+ throw new InvalidOperationException ( "must never get here" ) ;
47+ }
48+ }
49+
50+ static Task CloseOnFailure ( Task task , object state )
51+ {
52+ if ( task . IsFaulted )
53+ {
54+ return Close ( task , state ) ;
55+ }
56+ return TaskEx . Completed ;
57+ }
58+ }
59+ }
0 commit comments