Web Api C# - Task.Factory.startnew vs async

时间:2016-09-04 10:34:34

标签: c# asynchronous logging asp.net-web-api

我在我的端点中进行日志记录,将日志发送到单独的服务。我不希望将日志发送到服务的开销影响到客户正在使用的服务,而且如果日志有时无法完成,我也不在乎。因此,我一直在阅读关于如何简单地解雇和忘记的博客。我认为CPU密集型任务不应该使用异步,但我不知道IO相关任务有何不同,IO我的意思是调用另一个服务的端点,在这种情况下是为了记录。

此外,我似乎得到了相互矛盾的观点。一些博客说你永远不应该运行任何异步,因为这只需要从线程池中获取一个或多个线程,因此它与同步它没有什么不同。

Microsoft将async和await关键字引入到.Net 4.5中,他们说这些关键字应该用于整个端点,但是它还没有使用线程池中的一个或多个线程吗?最后我读过的一些stackoverflow帖子说使用Task.Factory.StartNew没问题,因为.Net会管理它。

有人可以澄清以上最佳做法,将日志发送到其他服务,因为我很困惑。

我考虑使用nlog是因为它的批处理和异步功能,但我不确定这是否是最好的方法。我不能使用像Hangfire这样的东西因为我没有sql后端。

提前致谢。

1 个答案:

答案 0 :(得分:8)

  

有些博客说你永远不应该运行任何异步,因为这只需要从线程池中获取一个或多个线程

不,这绝对不是真的。 async不使用线程池线程。 (有关详细信息,请参阅我的博文There Is No Thread)。

  

最后我读过的一些stackoverflow帖子说使用Task.Factory.StartNew没问题,因为.Net会管理它。

再次,不是真的。 StartNew是一个危险的API,不应该以这种方式使用。 (有关详细信息,请参阅我的博文StartNew Is Dangerous)。

  

因此,我一直在阅读有关如何简单解雇和忘记的博客。

由于您并不关心日志是否有时无法生成,因此我建议您使用HostingEnvironment.QueueBackgroundWorkItem。 QBWI不会阻止日志丢失,但它会尽力最小化日志丢失。只需使用Task.Run(或过时且危险的StartNew)将工作投入线程池,甚至不会尝试以最大限度地减少日志丢失。如果您要求您的日志是正确的,例如,用于结算或审核,则Hang​​fire适用于需要更强大功能的情况。 (有关详细信息,请参阅Fire and Forget on ASP.NET上的博文。