非等待的异步方法在中间件中 – 这是否有效并且是有效的模式?

huangapple go评论65阅读模式
英文:

Non awaited async method in middleware - does this work and is this a valid pattern?

问题

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.

Audit() 方法是一个异步方法,但没有等待它,可能是为了速度考虑,也许假设该调用不会导致管道延迟。开发者只是简单地添加了 "fire and forget" 注释。

Questions:

  1. .Audit 调用是否保证完成?如果是,通过哪个上下文运行此方法以完成?

  2. 在这个管道中以这种方式等待异步方法是否是有效的优化?这是否导致更快的管道?

  3. 这是否是可接受和有效的模式?

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
    }
}
英文:

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
    }
}

答案1

得分: 2

Sure, here are the translated parts:

Is the .Audit call guaranteed to complete? If so, which context is running this method through to completion?
没有,它不能保证任务完成。它将任务放入“TaskScheduler”以便完成。如果应用程序崩溃,数据将丢失。无论如何,似乎需要额外的“Task.Run”。

Is awaiting an async method in this pipeline in this way is a valid optimisation? Does this result in a faster pipeline?
很可能await会减慢管道的速度。

Is this an acceptable and valid pattern?
这取决于数据一致性的要求。

英文:

> 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.

huangapple
  • 本文由 发表于 2023年4月19日 23:07:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76056102.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定