From c029ad35059f84b924910639ad20bf7f53d50ac6 Mon Sep 17 00:00:00 2001 From: John Gathogo Date: Mon, 28 Mar 2022 22:47:11 +0300 Subject: [PATCH] ODataJsonLightCollectionReader improvements to reduce delegate allocations --- .../ODataCollectionReaderCore.cs | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.OData.Core/ODataCollectionReaderCore.cs b/src/Microsoft.OData.Core/ODataCollectionReaderCore.cs index 457797d0fe..15c5ab3a55 100644 --- a/src/Microsoft.OData.Core/ODataCollectionReaderCore.cs +++ b/src/Microsoft.OData.Core/ODataCollectionReaderCore.cs @@ -143,7 +143,8 @@ protected bool IsReadingNestedPayload public override sealed bool Read() { this.VerifyCanRead(true); - return this.InterceptException(this.ReadSynchronously); + + return this.InterceptException((thisParam) => thisParam.ReadSynchronously()); } /// @@ -153,7 +154,8 @@ public override sealed bool Read() public override sealed Task ReadAsync() { this.VerifyCanRead(false); - return this.ReadAsynchronously().FollowOnFaultWith(t => this.EnterScope(ODataCollectionReaderState.Exception, null)); + + return this.InterceptExceptionAsync((thisParam) => thisParam.ReadAsynchronously()); } /// @@ -228,9 +230,7 @@ protected bool ReadSynchronously() /// A task that when completed indicates whether more items were read. protected virtual Task ReadAsynchronously() { - // We are reading from the fully buffered read stream here; thus it is ok - // to use synchronous reads and then return a completed task - // NOTE: once we switch to fully async reading this will have to change + // Use synchronous read and then return a completed task return TaskUtils.GetTaskForSynchronousOperation(this.ReadImplementation); } @@ -313,11 +313,38 @@ protected void PopScope(ODataCollectionReaderState state) /// The type returned from the to execute. /// The action to execute. /// The result of executing the . - private T InterceptException(Func action) + private T InterceptException(Func action) + { + try + { + return action(this); + } + catch (Exception e) + { + if (ExceptionUtils.IsCatchableExceptionType(e)) + { + this.EnterScope(ODataCollectionReaderState.Exception, null); + } + + throw; + } + } + + /// + /// Catch any exception thrown by the action passed in; in the exception case move the reader into + /// state Exception and then rethrow the exception. + /// + /// The type returned from the + /// The action to execute. + /// + /// A task that represents the asynchronous operation. + /// The value of the TResult parameter contains the result of executing the . + /// + private async Task InterceptExceptionAsync(Func> action) { try { - return action(); + return await action(this).ConfigureAwait(false); } catch (Exception e) {