@@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1313using System ;
1414using System . Collections . Generic ;
1515using System . Diagnostics ;
16+ using System . Diagnostics . CodeAnalysis ;
1617using System . Security . Cryptography . X509Certificates ;
1718using System . Threading ;
1819using System . Threading . Tasks ;
@@ -76,7 +77,7 @@ protected EndpointBase(ServerBase server)
7677 }
7778
7879 /// <inheritdoc/>
79- public Task < IServiceResponse > ProcessRequestAsync (
80+ public ValueTask < IServiceResponse > ProcessRequestAsync (
8081 SecureChannelContext secureChannelContext ,
8182 IServiceRequest request ,
8283 CancellationToken cancellationToken = default )
@@ -670,7 +671,7 @@ public IServiceResponse Invoke(IServiceRequest request, SecureChannelContext sec
670671 {
671672 logger . LogWarning (
672673 "Async Service invoced sychronously. Prefer using InvokeAsync for best performance." ) ;
673- return InvokeAsync ( request , null ) . GetAwaiter ( ) . GetResult ( ) ;
674+ return InvokeAsync ( request , secureChannelContext ) . GetAwaiter ( ) . GetResult ( ) ;
674675 }
675676 return m_invokeService ? . Invoke ( request , secureChannelContext ) ;
676677 }
@@ -777,7 +778,7 @@ public void CallSynchronously()
777778 /// thread that calls IServerBase.ScheduleIncomingRequest().
778779 /// This method always traps any exceptions and reports them to the client as a fault.
779780 /// </remarks>
780- public async Task CallAsync ( CancellationToken cancellationToken = default )
781+ public async ValueTask CallAsync ( CancellationToken cancellationToken = default )
781782 {
782783 await OnProcessRequestAsync ( null , cancellationToken ) . ConfigureAwait ( false ) ;
783784 }
@@ -1042,7 +1043,7 @@ .Body is AdditionalParametersType parameters &&
10421043 else
10431044 {
10441045 // call the service even when there is no trace information
1045- m_response = await m_service . InvokeAsync ( Request , SecureChannelContext , cancellationToken )
1046+ m_response = await m_service . InvokeAsync ( Request , SecureChannelContext , cancellationToken )
10461047 . ConfigureAwait ( false ) ;
10471048 }
10481049 }
@@ -1074,26 +1075,25 @@ .Body is AdditionalParametersType parameters &&
10741075 /// <summary>
10751076 /// An object that handles an incoming request for an endpoint.
10761077 /// </summary>
1077- protected class EndpointIncomingRequest : IEndpointIncomingRequest
1078+ protected readonly struct EndpointIncomingRequest : IEndpointIncomingRequest , IEquatable < EndpointIncomingRequest >
10781079 {
10791080 /// <summary>
10801081 /// Initialize the Object with a Request
10811082 /// </summary>
10821083 public EndpointIncomingRequest (
10831084 EndpointBase endpoint ,
10841085 SecureChannelContext context ,
1085- IServiceRequest request )
1086+ IServiceRequest request ,
1087+ CancellationToken cancellationToken = default )
10861088 {
10871089 m_endpoint = endpoint ;
10881090 SecureChannelContext = context ;
10891091 Request = request ;
1090- m_tcs = new TaskCompletionSource < IServiceResponse > (
1091- TaskCreationOptions . RunContinuationsAsynchronously ) ;
1092+ m_vts = ServiceResponsePooledValueTaskSource . Create ( ) ;
1093+ m_service = m_endpoint . FindService ( Request . TypeId ) ;
1094+ m_cancellationToken = cancellationToken ;
10921095 }
10931096
1094- /// <inheritdoc/>
1095- public object Calldata { get ; set ; }
1096-
10971097 /// <inheritdoc/>
10981098 public SecureChannelContext SecureChannelContext { get ; }
10991099
@@ -1104,25 +1104,22 @@ public EndpointIncomingRequest(
11041104 /// Process an incoming request
11051105 /// </summary>
11061106 /// <returns></returns>
1107- public Task < IServiceResponse > ProcessAsync ( CancellationToken cancellationToken = default )
1107+ public ValueTask < IServiceResponse > ProcessAsync ( CancellationToken cancellationToken = default )
11081108 {
11091109 try
11101110 {
1111- m_cancellationToken = cancellationToken ;
1112- m_cancellationToken . Register ( ( ) => m_tcs . TrySetCanceled ( ) ) ;
1113- m_service = m_endpoint . FindService ( Request . TypeId ) ;
1114- m_endpoint . ServerForContext . ScheduleIncomingRequest ( this , m_cancellationToken ) ;
1111+ m_endpoint . ServerForContext . ScheduleIncomingRequest ( this , cancellationToken ) ;
11151112 }
11161113 catch ( Exception e )
11171114 {
1118- m_tcs . TrySetResult ( m_endpoint . CreateFault ( Request , e ) ) ;
1115+ m_vts . SetResult ( m_endpoint . CreateFault ( Request , e ) ) ;
11191116 }
11201117
1121- return m_tcs . Task ;
1118+ return m_vts . Task ;
11221119 }
11231120
11241121 /// <inheritdoc/>
1125- public async Task CallAsync ( CancellationToken cancellationToken = default )
1122+ public async ValueTask CallAsync ( CancellationToken cancellationToken = default )
11261123 {
11271124 using CancellationTokenSource timeoutHintCts = ( int ) Request . RequestHeader . TimeoutHint > 0 ?
11281125 new CancellationTokenSource ( ( int ) Request . RequestHeader . TimeoutHint ) : null ;
@@ -1157,7 +1154,7 @@ .Body is AdditionalParametersType parameters &&
11571154 using ( activity )
11581155 {
11591156 IServiceResponse response = await m_service . InvokeAsync ( Request , SecureChannelContext , linkedCts . Token ) . ConfigureAwait ( false ) ;
1160- m_tcs . TrySetResult ( response ) ;
1157+ m_vts . SetResult ( response ) ;
11611158 }
11621159 }
11631160 catch ( Exception e )
@@ -1166,8 +1163,7 @@ .Body is AdditionalParametersType parameters &&
11661163 {
11671164 e = new ServiceResultException ( StatusCodes . BadTimeout ) ;
11681165 }
1169-
1170- m_tcs . TrySetResult ( m_endpoint . CreateFault ( Request , e ) ) ;
1166+ m_vts . SetResult ( m_endpoint . CreateFault ( Request , e ) ) ;
11711167 }
11721168 }
11731169
@@ -1176,18 +1172,52 @@ public void OperationCompleted(IServiceResponse response, ServiceResult error)
11761172 {
11771173 if ( ServiceResult . IsBad ( error ) )
11781174 {
1179- m_tcs . TrySetResult ( m_endpoint . CreateFault ( Request , new ServiceResultException ( error ) ) ) ;
1175+ m_vts . SetResult ( m_endpoint . CreateFault ( Request , new ServiceResultException ( error ) ) ) ;
11801176 }
11811177 else
11821178 {
1183- m_tcs . TrySetResult ( response ) ;
1179+ m_vts . SetResult ( response ) ;
11841180 }
11851181 }
11861182
1183+ /// <inheritdoc/>
1184+ public override bool Equals ( object obj )
1185+ {
1186+ if ( obj is EndpointIncomingRequest other )
1187+ {
1188+ return Request . RequestHeader . Equals ( other . Request . RequestHeader ) ;
1189+ }
1190+ return false ;
1191+ }
1192+
1193+ /// <inheritdoc/>
1194+ public override int GetHashCode ( )
1195+ {
1196+ return Request . RequestHeader . GetHashCode ( ) ;
1197+ }
1198+
1199+ /// <inheritdoc/>
1200+ public static bool operator == ( EndpointIncomingRequest left , EndpointIncomingRequest right )
1201+ {
1202+ return left . Equals ( right ) ;
1203+ }
1204+
1205+ /// <inheritdoc/>
1206+ public static bool operator != ( EndpointIncomingRequest left , EndpointIncomingRequest right )
1207+ {
1208+ return ! ( left == right ) ;
1209+ }
1210+
1211+ /// <inheritdoc/>
1212+ public bool Equals ( EndpointIncomingRequest other )
1213+ {
1214+ return Request . RequestHeader . Equals ( other . Request . RequestHeader ) ;
1215+ }
1216+
11871217 private readonly EndpointBase m_endpoint ;
1188- private CancellationToken m_cancellationToken ;
1189- private ServiceDefinition m_service ;
1190- private readonly TaskCompletionSource < IServiceResponse > m_tcs ;
1218+ private readonly ServiceDefinition m_service ;
1219+ private readonly ServiceResponsePooledValueTaskSource m_vts ;
1220+ private readonly CancellationToken m_cancellationToken ;
11911221 }
11921222
11931223 /// <summary>
0 commit comments