diff --git a/DragonFruit.Common.Data/ApiClient.cs b/DragonFruit.Common.Data/ApiClient.cs index 5c6f3c2..027978f 100644 --- a/DragonFruit.Common.Data/ApiClient.cs +++ b/DragonFruit.Common.Data/ApiClient.cs @@ -204,55 +204,35 @@ protected virtual void SetupRequest(HttpRequestMessage request) /// to process the /// Whether to dispose of the produced after has been invoked. /// (optional) - protected Task InternalPerform(HttpRequestMessage request, Func> processResult, bool disposeResponse, CancellationToken token = default) + protected async Task InternalPerform(HttpRequestMessage request, Func> processResult, bool disposeResponse, CancellationToken token = default) { var (client, clientLock) = GetClient(); - var monitor = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); // post-modification SetupRequest(request); + HttpResponseMessage response = null; - // send request - // ReSharper disable once MethodSupportsCancellation (we need to run regardless of cancellation to release lock) - client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ContinueWith(async t => + try { - try - { - // evaluate task status and update monitor - switch (t.Status) - { - case TaskStatus.RanToCompletion: - monitor.SetResult(await processResult.Invoke(t.Result).ConfigureAwait(false)); - break; + // send request + // ReSharper disable once MethodSupportsCancellation (we need to run regardless of cancellation to release lock) + response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false); - case TaskStatus.Faulted: - monitor.SetException(t.Exception?.Flatten().InnerException ?? t.Exception); - break; + // evaluate task status and update monitor + return await processResult.Invoke(response).ConfigureAwait(false); + } + finally + { + request.Dispose(); - case TaskStatus.Canceled: - monitor.SetCanceled(); - break; - } - } - catch (Exception e) - { - monitor.SetException(e); - } - finally + if (disposeResponse) { - request.Dispose(); - - if (disposeResponse) - { - t.Result.Dispose(); - } - - // exit the read lock after fully processing - clientLock.Dispose(); + response?.Dispose(); } - }); - return monitor.Task; + // exit the read lock after fully processing + clientLock.Dispose(); + } } /// @@ -278,6 +258,8 @@ protected virtual async Task ValidateAndProcess(HttpResponseMessage respon } await stream.CopyToAsync(result).ConfigureAwait(false); + await stream.FlushAsync().ConfigureAwait(false); + result.Seek(0, SeekOrigin.Begin); return result as T; }