我在我的端点中进行日志记录,将日志发送到单独的服务。我不希望将日志发送到服务的开销影响到客户正在使用的服务,而且如果日志有时无法完成,我也不在乎。因此,我一直在阅读关于如何简单地解雇和忘记的博客。我认为CPU密集型任务不应该使用异步,但我不知道IO相关任务有何不同,IO我的意思是调用另一个服务的端点,在这种情况下是为了记录。
此外,我似乎得到了相互矛盾的观点。一些博客说你永远不应该运行任何异步,因为这只需要从线程池中获取一个或多个线程,因此它与同步它没有什么不同。
Microsoft将async和await关键字引入到.Net 4.5中,他们说这些关键字应该用于整个端点,但是它还没有使用线程池中的一个或多个线程吗?最后我读过的一些stackoverflow帖子说使用Task.Factory.StartNew没问题,因为.Net会管理它。
有人可以澄清以上最佳做法,将日志发送到其他服务,因为我很困惑。
我考虑使用nlog是因为它的批处理和异步功能,但我不确定这是否是最好的方法。我不能使用像Hangfire这样的东西因为我没有sql后端。
提前致谢。
答案 0 :(得分:8)
有些博客说你永远不应该运行任何异步,因为这只需要从线程池中获取一个或多个线程
不,这绝对不是真的。 async
不使用线程池线程。 (有关详细信息,请参阅我的博文There Is No Thread)。
最后我读过的一些stackoverflow帖子说使用Task.Factory.StartNew没问题,因为.Net会管理它。
再次,不是真的。 StartNew
是一个危险的API,不应该以这种方式使用。 (有关详细信息,请参阅我的博文StartNew
Is Dangerous)。
因此,我一直在阅读有关如何简单解雇和忘记的博客。
由于您并不关心日志是否有时无法生成,因此我建议您使用HostingEnvironment.QueueBackgroundWorkItem
。 QBWI不会阻止日志丢失,但它会尽力最小化日志丢失。只需使用Task.Run
(或过时且危险的StartNew
)将工作投入线程池,甚至不会尝试以最大限度地减少日志丢失。如果您要求您的日志是正确的,例如,用于结算或审核,则Hangfire适用于需要更强大功能的情况。 (有关详细信息,请参阅Fire and Forget on ASP.NET上的博文。