diff --git a/src/Microsoft.AspNetCore.Http/Internal/ReferenceReadStream.cs b/src/Microsoft.AspNetCore.Http/Internal/ReferenceReadStream.cs index be51a2f487..8a8c1e95de 100644 --- a/src/Microsoft.AspNetCore.Http/Internal/ReferenceReadStream.cs +++ b/src/Microsoft.AspNetCore.Http/Internal/ReferenceReadStream.cs @@ -139,19 +139,28 @@ namespace Microsoft.AspNetCore.Http.Internal if (callback != null) { - try + // Offload callbacks to avoid stack dives on sync completions. + var ignored = Task.Run(() => { - callback(tcs.Task); - } - catch (Exception) - { - // Suppress exceptions on background threads. - } + try + { + callback(tcs.Task); + } + catch (Exception) + { + // Suppress exceptions on background threads. + } + }); } } public override int EndRead(IAsyncResult asyncResult) { + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } + var task = (Task)asyncResult; return task.GetAwaiter().GetResult(); } diff --git a/src/Microsoft.AspNetCore.WebUtilities/BufferedReadStream.cs b/src/Microsoft.AspNetCore.WebUtilities/BufferedReadStream.cs index f9ea281d05..6cf2fa7d11 100644 --- a/src/Microsoft.AspNetCore.WebUtilities/BufferedReadStream.cs +++ b/src/Microsoft.AspNetCore.WebUtilities/BufferedReadStream.cs @@ -229,7 +229,18 @@ namespace Microsoft.AspNetCore.WebUtilities tcs.TrySetResult(toCopy); if (callback != null) { - callback(tcs.Task); + // Offload callbacks to avoid stack dives on sync completions. + var ignored = Task.Run(() => + { + try + { + callback(tcs.Task); + } + catch (Exception) + { + // Suppress exceptions on background threads. + } + }); } return tcs.Task; } @@ -239,6 +250,11 @@ namespace Microsoft.AspNetCore.WebUtilities public override int EndRead(IAsyncResult asyncResult) { + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } + Task task = asyncResult as Task; if (task != null) { diff --git a/src/Microsoft.AspNetCore.WebUtilities/FileBufferingReadStream.cs b/src/Microsoft.AspNetCore.WebUtilities/FileBufferingReadStream.cs index 06f9de2644..ada0c67bf4 100644 --- a/src/Microsoft.AspNetCore.WebUtilities/FileBufferingReadStream.cs +++ b/src/Microsoft.AspNetCore.WebUtilities/FileBufferingReadStream.cs @@ -232,19 +232,28 @@ namespace Microsoft.AspNetCore.WebUtilities if (callback != null) { - try + // Offload callbacks to avoid stack dives on sync completions. + var ignored = Task.Run(() => { - callback(tcs.Task); - } - catch (Exception) - { - // Suppress exceptions on background threads. - } + try + { + callback(tcs.Task); + } + catch (Exception) + { + // Suppress exceptions on background threads. + } + }); } } public override int EndRead(IAsyncResult asyncResult) { + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } + var task = (Task)asyncResult; return task.GetAwaiter().GetResult(); } diff --git a/src/Microsoft.AspNetCore.WebUtilities/MultipartReaderStream.cs b/src/Microsoft.AspNetCore.WebUtilities/MultipartReaderStream.cs index c94b27b003..09f11959df 100644 --- a/src/Microsoft.AspNetCore.WebUtilities/MultipartReaderStream.cs +++ b/src/Microsoft.AspNetCore.WebUtilities/MultipartReaderStream.cs @@ -184,19 +184,28 @@ namespace Microsoft.AspNetCore.WebUtilities if (callback != null) { - try + // Offload callbacks to avoid stack dives on sync completions. + var ignored = Task.Run(() => { - callback(tcs.Task); - } - catch (Exception) - { - // Suppress exceptions on background threads. - } + try + { + callback(tcs.Task); + } + catch (Exception) + { + // Suppress exceptions on background threads. + } + }); } } public override int EndRead(IAsyncResult asyncResult) { + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } + var task = (Task)asyncResult; return task.GetAwaiter().GetResult(); }