Context in C#

Here’s the translation of the Go code to C# with explanations in Markdown format suitable for Hugo:

Our first example demonstrates the usage of HttpContext for controlling cancellation in an ASP.NET Core application. The HttpContext carries request-scoped values and cancellation signals across the application.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/hello", async context =>
            {
                Console.WriteLine("server: hello handler started");
                try
                {
                    await HandleHelloRequest(context);
                }
                finally
                {
                    Console.WriteLine("server: hello handler ended");
                }
            });
        });
    }

    private async Task HandleHelloRequest(HttpContext context)
    {
        var cancellationToken = context.RequestAborted;

        try
        {
            await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
            await context.Response.WriteAsync("hello\n");
        }
        catch (TaskCanceledException)
        {
            Console.WriteLine($"server: {cancellationToken.IsCancellationRequested}");
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            await context.Response.WriteAsync("Request was cancelled");
        }
    }
}

In this C# example, we’re using ASP.NET Core to set up a simple HTTP server. The HandleHelloRequest method simulates some work the server is doing, while keeping an eye on the cancellation token for a signal that we should cancel the work and return as soon as possible.

To run the server:

$ dotnet run

Simulate a client request to /hello, hitting Ctrl+C shortly after starting to signal cancellation:

$ curl http://localhost:5000/hello
server: hello handler started
^C
server: True
server: hello handler ended

In this example, the HttpContext.RequestAborted property provides a CancellationToken that is triggered when the request is aborted. This is similar to the context.Done() channel in the original Go example.

The try-catch block in the HandleHelloRequest method catches the TaskCanceledException that is thrown when the task is cancelled. This is equivalent to checking the ctx.Err() in the Go version.

Note that ASP.NET Core automatically handles a lot of the setup that we had to do manually in the Go version, such as creating the server and routing requests.