0

I've come across this code in one of our applications (ASP.NET MVC .NET 7 c#). This code is injected into the middleware pipeline.

The Audit() method is an async method but it's not awaited, presumably for speed reasons, perhaps assuming that the call will not cause any delay in the pipeline. The dev has simply commented "fire and forget".

Questions:

  1. Is the .Audit call guaranteed to complete? If so, which context is running this method through to completion?

  2. Is awaiting an async method in this pipeline in this way is a valid optimisation? Does this result in a faster pipeline?

  3. Is this an acceptable and valid pattern?

public class LoggingMiddleware : IMiddleware
{
    private readonly IAuditService _auditService;

    public LoggingMiddleware(IAuditService auditService)
    {
        _auditService = auditService;
    }

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        await next.Invoke(context);

        _ = _auditService.Audit(context); // fire and forget
    }
}
SimonGoldstone
  • 5,096
  • 3
  • 27
  • 38
  • 1
    Here are might thoughts about it: 1. _auditService.Audit is not guaranteed to complete if it throws an exception 2. sure it could be faster not to await but its not recommended. you could measure if its worth it. 3. Yes Fire & Forget can be a valid pattern in some cases. – jeb Apr 19 '23 at 15:25
  • 1
    If Audit is returning a Task and it is not awaited, shouldn't the compiler generate a warning here? – rene Apr 19 '23 at 15:29
  • 1
    Probably relevant: https://stackoverflow.com/questions/15522900/how-to-safely-call-an-async-method-in-c-sharp-without-await – rene Apr 19 '23 at 15:31
  • 2
    I belive if the discard parameter _ is used it's not a warning. – jeb Apr 19 '23 at 15:31

1 Answers1

2

Is the .Audit call guaranteed to complete? If so, which context is running this method through to completion?

No, it does not guarantee task completion. It puts task to TaskScheduler for completion. If application crashes data will be lost. Anyway looks like additional Task.Run is needed here.

Is awaiting an async method in this pipeline in this way is a valid optimisation? Does this result in a faster pipeline?

Most likely await will slowdown pipeline.

Is this an acceptable and valid pattern?

It depends on requirements of data consistency.

Svyatoslav Danyliv
  • 21,911
  • 3
  • 16
  • 32