【问题标题】:How do you perform completely asynchrouns operations in ASP NET Core如何在 ASP NET Core 中执行完全异步操作
【发布时间】:2020-06-05 15:01:00
【问题描述】:

您好,我正在尝试为我的一些API 端点做跟踪日志。这些日志是在调用端点时生成的。我希望以异步方式完成日志的写入(就像轻量级一样可能),以免影响我通常逻辑的性能。

我想有一个可注入的组件,并且可以在生成日志时在我的端点的任何位置调用。问题是我似乎找不到合适的异步解决方案:

无需延误的重要服务

public interface IImportantInterface
{
    Task DoSomethingUndistrubedAsync(string value);
}

**Wrapper around Redis pub-sub**

 public interface IIOService{
     Task PublishAsync( object obj);
 }

控制器

public class Controller
{
    private IImportantInterface importantService;
    private Publisher publisher;
    [HttpPost]
    public async Task SomeEndpointAsync(){
          this.publisher.Publish([some_log]);
          await this.importantService.DoSomethingUndisturbedAsync([something]);
    }
    public Controller(IImportantInterface importantService)
    {

        this.importantService=importantService;
    }

}

现在真正的问题来了。我如何为我的Publisher 制作最小的足迹。我想出了 3 个方案,但其中两个由于超出范围而无法实现:

尝试 1
任务范围为方法的瞬态服务:

public class Publisher{

    private IIOService writeService{get;set;}
    public async Task PublishAsync(object obj){
         Task t1=Task.Run(async()=>await writeService.PublishAsync(obj)); //t1 might not finished when method exits
    }
}

到方法结束时,任务 t1 可能还没有完成。

尝试 2 嵌入在 Transient Service 中的任务

public class Publisher{    //publisher might get discarded when calling controller gets out of scope
     private Task t1;
     private IIOService writeService{get;set;}
     public async Task PublishAsync(object obj){        
          t1=Task.Run(async ()=> this.IIOService.writeService(obj));  
     }
}

现在任务不会在方法作用域之后被收集,但在调用Controller方法类超出作用域时它可能不会完成

尝试 3 具有 Tasks 的 ConcurrentQueue 的单例对象被入队。 这不会超出范围,但我什么时候可以清除这些项目?

public class Publisher{
     private ConcurrentQueue<Task> Queue;
     public async Task PublishAsync(object obj){
         this.Queue.Enqueue();
     }
}

P.S 我想将这些日志发布到一个公共的地方。从那个地方,目标是使用 pub-sub 功能发布到 Redis 数据库。 我应该写信给 Redis 吗?

【问题讨论】:

    标签: asp.net-core redis task-parallel-library publish-subscribe


    【解决方案1】:

    您好,我正在尝试为我的一些 API 端点做跟踪日志。这些日志是在调用端点时生成的。我希望以异步方式(尽可能轻量级)完成日志的写入以免影响我平时逻辑的表现。

    我强烈建议您使用现有且经过详尽测试的日志库,其中有许多具有现代功能,例如语义日志记录和异步兼容的隐式状态。

    现代日志库通常采用单例设计,日志保存在内存中(并且日志记录方法是同步的)。然后有一个单独的“处理器”将这些消息发布到收集器。如果您坚持编写自己的日志框架(为什么?),我建议您采用与所有其他非常成功的日志框架相同的方法。

    【讨论】:

    • 我已经在使用Serilog 记录一般内容,但我需要将此special 日志发布在Redis 频道中。
    • 那么我会为 Redis 编写一个 Serilog 接收器。或use an existing one.
    • 但是Serilog 怎么知道将正常日志写入Destination1special 日志到Redis
    • 我对 Serilog 不是很熟悉,但我会尝试使用过滤后的sub-loggers
    猜你喜欢
    • 2019-02-09
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多