【发布时间】: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