Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add async APIs to push users aways from sync over async patterns #164

Open
twsouthwick opened this issue Aug 24, 2022 · 2 comments
Open
Milestone

Comments

@twsouthwick
Copy link
Member

twsouthwick commented Aug 24, 2022

Summary

A number of APIs in .NET Core are async aware and probably should have been in .NET Framework. However, when adapting the behavior of core behind the APIs framework had ends up with a number of sync over async patterns. We should provide a way forward here that will guide people to using async.

Motivation and goals

We should provide async methods that end up calling into async pathways on .NET Core. Currently, this is handled either by invoking required async pathways in middleware or by calling GetAwaiter().GetResult().

In scope

This would ideally provide APIs that users on framework, core, and standard could all use. Depending on where things run, it would either be true async (i.e. on ASP.NET Core) or just return a completed task (i.e. on ASP.NET Framework).

Initial APIs identified:

  • HttpRequest.InputStream
  • HttpResponse.End()
  • HttpResponse.TransmitFile
  • HttpResponse.SendFile

probably some more (especially those that rely on any of these APIs).

Out of scope

  • No plans to make ASP.NET Framework more async aware

Risks / unknowns

  • Developers may think this is making ASP.NET Framework async aware

Examples

Currently:

public void SomeFunc(HttpResponse response)
{
  response.TransmitFile("some-path");
}

after:

public async Task SomeFunc(HttpResponse response)
{
  response.TransmitFileAsync("some-path");
}

Design considerations

  • A number of these APIs are also exposed on the *Base and *Wrapper types. Would need to identify how to handle those
  • Since we're type forwarding to System.Web.dll on framework, we will probably want to provide any async functionality as extension methods that would forward to the non-async on framework while using actual async behavior on ASP.NET Core
@davidfowl
Copy link
Member

I don't think we should do this. We don't want to change/extend this type at all.

@GerardSmit
Copy link

GerardSmit commented Jul 11, 2023

Since this isn't planned: when the interfaces like IHttpResponseEndFeature are publicly available (which been suggested for mocking #332 (comment) and has been added to the milestone 1.3) we could make our own extension methods:

using System.Threading.Tasks;
using HttpResponse = System.Web.HttpResponse;

#if NET8_0_OR_GREATER

// ASP.NET Core implementation
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http.Features;
using HttpResponseCore = Microsoft.AspNetCore.Http.HttpResponse;

namespace SystemWeb
{
    public static class HttpResponseExtensions
    {
        [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_response")]
        private static extern HttpResponseCore GetResponse(HttpResponse @this);

        public static Task EndAsync(this HttpResponse @this)
            => GetResponse(@this).HttpContext.Features.GetRequiredFeature<IHttpResponseEndFeature>().EndAsync();
    }
}

#else

// ASP.NET implementation
namespace SystemWeb
{
    public static class HttpResponseExtensions
    {
        public static Task EndAsync(this HttpResponse @this)
        {
            @this.End();
            return Task.CompletedTask;
        }
    }
}

#endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants